our akkoma instance: weird journey on real world problems, especially as a third world country user

here is fedinet.waltuh.cyou, my very experimented akkoma instance that's probably ever done. there are many customizations that has been done in the backend and frontend side, too.

the screenshot of the akkoma in web

it has been the second month of me maintaining this thing all on my own. behind of this simple looking thing, there's actually some great amount of effort that has been done with this very setup.

the setup

if i draw the entire thing as a diagram, it looked like this:

the entire akkoma diagram

you see, usually you only put akkoma backend here and it's “that's it” most of the time. This works, usually. but not on our very setup where we are relying on contabo storage, which often times has failures (eg, random outage, timeouts, instability, etc).

and so that's how the journey starts. i guess?

problem 1: the medias is big, and akkoma handled it wrong, by default

generally, nobody is wrong on how they're uploading their avatar, banner, medias, and etc. for this one, it's mostly on how we serve it to the client.

and there's also nothing wrong on trying to preserve the original as much as possible.

so much so, we ended up serving a big image on a small <img>: the google pagespeed report that points onto user avatar

this is no problem for those with fast and unlimited internet, but became a problem to those with bad peering route to the server (which causes connection/loading to the server to became rather slow), and those that's in limited bandwidth (roaming users, i see you).

to fix this, we can enable media proxy that's in our server, and then enable post thumbnailing. this, works. but somewhat terrible in several ways. the mediaproxy in akkoma here: – can only process what's on jpg – anything else are being redirected / served raw

the thing is, some niche & weeb communities that's in fedi are mostly posting their favourite fanarts in PNG, which barely fix the main bandwidth problem.

let's remember this: an 20 seconds long high quality animated GIF is bigger than a video with the same duration and size. which then ended up with: – your user's browser loaded 20 MB of GIF that they never interacted or expand with. – your user that scroll past through a post with multiple raw camera photos will load atleast 5 MB per images without even expanding – a pixel GIF being bigger than an animated webp.

a problematic bandwidth problem, a problematic solution, well. it seems we're stuck and we began to think of switching client or the entire software server entirely that has zero issues with these.

and so,

here comes mediaproxyoma

you see, for media thumbnailing, pleroma apparently has began using libvips for the thumbnailing processes, while akkoma to this day is still... relying on an deprecated convert command by imagemagick to maintain compatibilities with debian host.

to be frank, if you have read my previous post on the waltuh.cyou setup, the host is actually also running debian. The only differences here is that i'm isolating every single services via an container using incus with each container using alpine linux as the base in order to get the latest dependencies. so, how do i fix the problem here?

i make my own media proxy backend. yeah. that's what i did. since i already have an image compressor proxy backend called go-bwhero, pairing it with mediaproxyoma seems ended up giving a great match. One process mostly focusing on proxying, and the other processing and making thumbnail of the image.

so, after some testing, i run the media proxy backend in my server, immediately changed any path that goes to /proxy/* to this backend instead. initially, it has several bugs, but then after several reports and spotted problems, it's working pretty much really well ever since then.

the same goes to go-bwhero. after several experiments, I ended up adjusting several parameters that speeds up the processing to be just 0.4-1.1 seconds on average.

here's the snippet of out Caddyfile. Our akkoma backend is listening on 10.154.198.6:4000 and the mediaproxyoma backend is listening on 10.154.198.11:8080:

fedinet.waltuh.cyou {
  log {
    output file /var/log/caddy/akkoma.log
  }

  encode zstd gzip

  reverse_proxy 10.154.198.6:4000
}


media.fedinet.waltuh.cyou {
  @mediaproxy path /proxy/*

  log {
    output file /var/log/caddy/media_fedinet.log
  }

  handle @robots {
    header Content-Type text/plain
    respond "User-agent: *
Disallow: /"
  }

  handle @mediaproxy {
    reverse_proxy 10.154.198.11:8080 {
      transport http {
        response_header_timeout 32s
        read_timeout 32s
      }
    }
  }
}

problem 2: it's redownloading the same exact things

hooray! we now have a proper image compression that saves a lot of user bandwidth. now what?

GUESS WHAT,

EMOJI FILES KEPT BEING REFETCHED ON EVERY WEB SESSION THAT WE OPEN. So did wallpaper, banner, user avatars, emojis, EVERYTHING. Guess what that means? The bandwidth is still not solved!

Introducing: immutable in Cache-Control

The immutable response directive indicates that the response will not be updated while it's fresh

it doesn't matter what your concern here, but hear me out: emojis files, user avatars endpoint, thumbnails, and practically any media endpoints that we knew are mostly ended up giving the same bytes. since akkoma-fe itself will refetch these again to the server, it's going to be another waste of duplicate bandwidth.

so, we decided to set our Cache-Control to be this:

Cache-Control: public, max-age=1209600, immutable

then, we apply it to these endpoints: – /emoji/*, /static/js/*, and /static/css/* on akkoma fe endpoint – /media/* on our varnish setup – /proxy/* on our mediaproxyoma

so, our Caddyfile looked like this now:

fedinet.waltuh.cyou {
  @static path /static/js/* /static/css/* /emoji/*

  log {
    output file /var/log/caddy/akkoma.log
  }

  encode zstd gzip

  handle @static {
    reverse_proxy 10.154.198.6:4000 {
      @success status 2xx

      handle_response @success {
        header Cache-Control "public, max-age=1209600, immutable" {
          defer
        }
        copy_response
      }
    }
  }

  reverse_proxy 10.154.198.6:4000
}

update Feb. 23th 2026: our forked akkoma-be now set the immutable cache-control flag, so this reverse proxy approach is no longer needed, unless you're running the original akkoma/pleroma backend.

notice that we did not alter mediaproxyoma. That's because, mediaproxyoma has set this by default on the backend, so did our varnish setup sets it too.

as the result, the next time user refresh or open akkoma-fe again, the browser only loads what's not being cached, and then use what's being cached, effectively reducing a large amount of bandwidths, and the web loads faster.

problem 3: the avatar, cover/banner, and even our local posts is still big.

we have neutralized the damage a bit. but now we face the real problem: the avatar being bigger than the post thumbnail. what sorcery is this?

this is actually a problem in akkoma-fe where the original code choose to load the original image instead so animated avatar remains working because apparently, mediaproxy implementation in akkoma here has a very limited capabilities on thumbnailing as i've mentioned previously.

this is understandable... but, we're using our own my own media proxy backend, which: – convert literally any kind of known supported image formats to webp – convert GIF to animated WEBP quick enough (seriously, i converted a 21 MB of 60 FPS gif to Animated WEBP, ended up just sized 2 MB, all while just taking 1.8 seconds) – thumbnail a video to webp quick enough

and guess what we do this time.

we fork akkoma-fe, with several changes: – use THUMBNAILED ENDPOINT for PFP and COVER (except for viewing the original) – NEVER AUTOLOAD VIDEO, Even just the metadata. We read the thumbnail by using poster attribute that's in <video> element instead.

as the result? previously, it took like 50 MB to load at first, but now:

WE NOW ONLY USE 25 MB ON FIRST LOAD!

WE NOW ONLY USE 25 MB ON FIRST LOAD!

look at these. the video showed 0 seconds literally means that we didn't preload anything: screenshot of a post with a video the same thing but different video again and again

now look. we got it working, but now we also want to treat the same to our local users that upload medias. akkoma-be, for the same mediaproxy limitation reason, it bypass anything from local upload. Makes sense, But not for us (where the media server is literally hosted outside of our host).

since we're using our own mediaproxy implementation, as usual, we forked akkoma-be too, fix the problem, and it works in fedinet.waltuh.cyou.


for the changes itself, i've sent some to the upstream, but after realizing how limited their mediaproxy implementations are, i decided to draft the two PRs that i made: – https://akkoma.dev/AkkomaGang/akkoma/pulls/1067https://akkoma.dev/AkkomaGang/akkoma-fe/pulls/482


closing

should you try these tricks that i've made tho?

well, i would say, it depends. But if you also want to make sure that user from third world country to be able to enjoy using your instance, Then you probably also want to follow the same approach that i do.

the reason i did all of these is because i am an user from third world country myself. that should give you an enough picture already.

mediaproxyoma and go-bwhero, the thing that i wrote, is surprisingly low on memory usage even after thousand of traffics everyday.

well, that's it. thank you for reading my silly journey.

if you're interested though, you can try replicate my setup