Codeberg is (most likely) not under attack

I am writing this post so I can link a static reference during future downtimes of Codeberg without having to compose the same comment/opinion from scratch. This refers to the discussions happening under the #codeberg hashtag on Mastodon and Bluesky, and on Reddit.

Disclaimer

I am a professional sysadmin and de-facto SRE (site reliability engineer). “De-facto” because I never officially held a position with that title, but I am doing exactly that: ensuring services are up at all times and usable for whoever the audience is.

Scope

This post also has nothing to do with my personal view on Codeberg as a platform or association or its recent decisions. I had this post in mind for a long time already. It’s solely about the technical topic of site reliability and “attacks”, as people often label it on social media.

Stop writing about “attacks” until someone in charge has told you the underlying reason Link to this section

Whenever Codeberg is down and people have noticed, some of them start posting on social media to state the obvious and (very often) pair it with a message like “codeberg is under attack again, fuck XYZ”.

Please stop this!

At this point in time you have no information about the reason for the downtime, unless you have access to their systems. And nobody with access would make such a post.

What to do instead:

  • Check Codeberg’s status page and their official announcement channels first. If there is an incident note, it will be there before it is on your timeline.
  • If you post, post the observation and not the cause: “Codeberg is down for me (since 14:20 UTC)” is useful, “Codeberg is under attack again” is not.
  • Then wait. The people who could tell you the reason are the people currently busy fixing it.

What “attacks” actually are, and what they are not Link to this section

OK, let’s define what “attacks” actually mean here. When people use this word, they want to express a spike in requests to the site, coordinated by a central actor with the goal of overloading the site and bringing it down. This is commonly known as DDoS (distributed denial of service).

DDoS attacks can happen in two ways: many requests from a single IP or a few IPs, or many individual requests from a (very) large fleet of unique IPs. The former is pretty easy to act on, the latter isn’t. However, the latter also isn’t something any random “hacker” can just do so easily. Getting access to so many IPs that you could orchestrate a DDoS attack costs a lot of money in the first place and will very likely get you banned if you are using any rented infrastructure. If the hosting provider has your actual verified credentials, it might even get you in trouble legally. DDoS is not just a fun troll task.

What is mostly happening, though, is just “ordinary” scraping. Scraping doesn’t aim to bring the instance down; it tries to stay undetected and collect data. Many scrapers increase their activity automatically if they get many 200s back (the response code indicating success), and at some point the underlying system can’t process all the requests “in time” anymore, hence the service feels “slow”. If multiple scrapers act in parallel, the site becomes “very slow”, up to the point where certain requests time out and others just make it in before the timeout. This slowness is what users experience most often on Codeberg. Yes, a small part of these requests also comes from actual users, and they must be served on top of the scrapers then. Codeberg does not publish concurrency numbers, but assuming a few hundred to maybe a thousand concurrent users when it’s up, this might already have a bit of influence on the load.

None of this means that Codeberg has never actually been attacked, and both cases are something entirely different from the “ordinary” scraping described above. In January 2024, their provider confirmed an incoming DDoS that saturated the uplink of their server: “an inrush of junk data at the maximum link speed”. Codeberg stayed only partially reachable for more than a day and ran several services IPv6-only while IPv4 was filtered. In February 2025 they were hit by a coordinated abuse campaign that Codeberg themselves attributed to far-right actors targeting projects advocating tolerance and equal rights. It came as mass spam in issue trackers and thousands of abusive mentions, with a volumetric denial-of-service attack clogging their internet connection on top.

Note what both cases have in common, though: we know about them because the people running the platform said so, in public, with details. Nobody had to guess it from a slow page load.

Downtime is most often caused by other problems than “attacks” Link to this section

However, most often a downtime is not caused by scraping or coordinated attacks. Once a site becomes unresponsive, scrapers stop, and attackers usually do as well, as they have reached their goal (yes, some might monitor and wait until it’s back up to start again, but these are the exceptions). So when the service got restarted, the sysadmin (hopefully) has checked the reason and at least put a ban in place for certain IP ranges or request paths, so that the same pattern can’t just continue, and the service should be up and running again after a few minutes of downtime (assuming that the downtime was noticed immediately).

If the downtime starts to exceed the first hour, it is very likely that there are other reasons for it. Here’s a list of possible reasons:

  • No admin has noticed the downtime yet (this happens if only one person is in charge or there is no push notification in place to alert them)
  • The disk is full
  • The disk has a failure and the automated switchover didn’t work
  • The underlying database has a severe issue (lost quorum, data is out of sync, etc.)
  • Electricity issue on the provider side
  • A different service running on the host goes berserk and takes all CPU/memory on the host

These issues are usually much more complex to detect in the first place and then to troubleshoot properly. You often can’t go below a few hours, even when aiming for a “quick fix” just to get the service back up. In some cases you can’t even do that, because it would leave the instance in a “weak state” and require another downtime soon after to “clean up”.

Which brings me to the actual point of this post: a site being down tells you nothing about why it is down. “Slow” and “unreachable” feel identical from the outside, and the causes behind them rarely have anything to do with somebody targeting the platform.

The claim “AI bros/tools are bringing Codeberg down” Link to this section

AI crawlers do cause a large share of today’s scraping traffic, and that traffic does make instances slow. But causing load as a side effect is not the same as attacking something. Nobody is spending real money on a crawler fleet to take Codeberg offline: they want the data, and an instance that is down gives them exactly nothing. That distinction is not pedantry: it decides the response. “We are under attack” points at an actor and at law enforcement, while “we are being scraped harder than our current protections handle” points at proxy rules, rate limits and capacity, which is the thing that actually helps. Picking an actor that is disliked by default and pushing the blame onto them is emotionally satisfying and analytically useless. Seeing it in bulk under the #codeberg hashtag also makes the whole community look unprofessional. If you have these thoughts, rather stay quiet than populating to a (negative) public perception of your community.

Most of what happens is just “normal scraping”, and every instance can protect itself from it by using “proper” proxy rules/ACLs. Getting these right and effective might take a while and many iterations, but you’ll get there. You’ll find patterns (e.g. uncommon user agents, weird request paths) that these scrapers use, and you’ll be able to (at least partly) block them. Paired with dynamic IP-based blocklists (e.g. Ultimate-Hosts-Blacklist/Ultimate.Hosts.Blacklist), you are able to protect yourself in a way that doesn’t let your instance go down every now and then. I say this as someone who applies these measures daily and has had “success” with them.

Here is an example of how this might look on the proxy side:

Example of denied vs. allowed requests

(This is one of my instances, not Codeberg’s, so treat it as an illustration of the pattern and not as a measurement of their traffic.) The yellow requests are the blocked ones. ~20-40 blocked requests per second add up to somewhere between 70k and 140k blocked requests per hour. Serving all of these would make any instance “slow”, depending on how beefy the hardware handling it is.

Of course, Codeberg is not doing nothing: at some point they used challenge-based protections in front of their platform (they still do for some request paths if I remember correctly) and have been iterating on their proxy rules publicly for a while. On top of that, their request volume is orders of magnitude above anything a personal instance sees. They surely need other/additional rules than random homelab instances, simply due to the increased interest of scrapers in their instance. So “just add (more) proxy rules” is not the only missing piece but just one part of the bigger picture. What I think is missing in addition sits further up the stack: consistent detection, alerting and recovery, so that an incident is measured and can be tackled in minutes rather than hours. (There’s likely more on the processes/operations side of things that should be improved but this would be mainly guessing territory from the (meanwhile) outside view of mine).

To conclude: the best thing you can do during the next outage is boring: check the status page, wait for the people in charge, and resist the urge to name a culprit.