Epiktistes

Epiktistes is my home in the Fediverse. It is an instance of Ktistec, a single-user ActivityPub server like Mastodon, but with fewer users and fewer commits. Here's my introduction (last updated early-2025).

I wrote a series of posts about optimizing the performance of the Ktistec server, its build time, and its executable size: part 1, part 2, part 3, part 4, and part 5.

Some things I regularly write about, organized by hashtag:

I also wrote some #pointfreeverse.

Todd Sundsted

maintaining an open source package is a difficult, often thankless job.

diving in out of nowhere and giving these volunteers shit is a fucked move. same as diving in to any other conversation you weren't invited to.

i'm thinking of Andrew Tridgell and rsync here, but it applies broadly.

Todd Sundsted

RE: mastodon.social/users/bagder/s

This is a very interesting thread! According to @bagder

  • None of these used Mythos
  • LLMs/AI are driving these vulnerability findings
  • Many of them have been in the code a very long time

The current situation is overwhelming.

If you use curl (or free software in general) consider supporting developers while they work through the tidalwave. I use curl and just sent my support. You should too!

daniel:// stenberg://

not even half-way through this #curl release cycle we are already at 11 confirmed vulnerabilities - and there are three left in the queue to assess and new reports keep arriving at a pace of more than one/day

11 CVEs announced in a single release is our record from 2016 after the first-ever security audit (by Cure 53).

Todd Sundsted

today i learned how to reliably peg a single CPU at 100%. what do you all use?

yes > /dev/null &

#til

Todd Sundsted
queensrÿche on stage

queensrÿche playing at epcot.

"silent lucidity" may or may not have been part of my upbringing.

Todd Sundsted

sometimes, with software, it feels like everything is possible but nothing is easy...

Todd Sundsted
Release v3.4.0 of Ktistec

The biggest change in release v3.4.0 of Ktistec is cursor-based pagination for all web-navigable collections (timeline, notifications, etc.). Offset-based pagination will be removed completely in the next release.

Offset-based (e.g. page/size) pagination works well on collections that don't change. But, what does "the second page" contain in a dynamic timeline? Support for cursor-based pagination is required by the Mastodon-compatible API, but has been a desirable feature for quite a while.

While updating queries to paginate by cursor, I also made performance improvements to the queries themselves, as mentioned elsewhere. Scrapers and bots have already adapted—sort of. I now see odd hybrid requests in the log like /tags/xyz?page=7&min_id=123. Overall CPU usage under normal load is now sitting at 0-1%.

Here is the full changelog for the release:

Added

  • Cursor-based pagination for web-navigable collections. (fixes #122)
  • Mastodon-compatible API: /api/v1/timelines/tag/:hashtag endpoint.

Fixed

  • Negative replies count when viewing a post that is also a reply.
  • Order cached actors' posts by published rather than id.

Changed

  • Report 401 and 403 as distinct errors in Ktistec::Network.get.

Removed

  • Unused paginated query methods.

Enjoy!

#ktistec #crystallang #activitypub #fediverse

Todd Sundsted

while replacing page/size pagination with cursor-based pagination throughout ktistec, i took the opportunity to optimize queries. various changes—like leveraging the natural sort order of existing indexes—improved performance across the board by about 10x. that number is a little bit misleading—queries that took ~10msec now take less than 1msec, but that isn’t much in absolute terms. still, it moves the bottleneck!

#ktistec

Todd Sundsted
Release v3.3.9 of Ktistec

Release v3.3.9 of Ktistec continues the security hardening work from recent releases, with further progress on the Mastodon-compatible API.

Of note: all network connections now go through a new Ktistec::Network module. This allows Ktistec to limit the size of HTTP bodies it reads, on both inbound and outbound requests, and ensures it only opens connections to valid remote IP addresses.

Here's the full changelog:

Added

  • New Mastodon-compatible APIs.

Fixed

  • Close DNS rebinding window for outbound HTTP requests.
  • Limit the size of HTTP bodies the server reads.
  • Sanitize RSS feed output to prevent CDATA breakout.
  • Destroy all sessions and access tokens on account termination.

Changed

  • Ensure all GET and POST requests utilize Ktistec::Network.
  • Process local recipients in-process in inbox/outbox activity processors.

As always, it's worth upgrading for the security fixes!

#ktistec #crystallang #activitypub #fediverse

Todd Sundsted

I don't have a large number of followers, but a recent reply to a relatively short thread (< 10 total posts) resulted in 247 HTTP GETs in the first 100 seconds after the post. Only 29 of those were requests for the object. 218 were requests for the object's replies, which surprised me—why do servers poll for replies within the first 100 seconds? Mean response time was 481μs—well under 1ms. Peak throughput hit 20 req/s.

#ktistec

Todd Sundsted

how widely adopted/supported/implemented is FEP-8a8e? is that a safe direction to converge for federated events?