
At the start of the summer, Arc had four contributors. Today it has nine.
Most of the new ones had never landed a change in a database before. Several had never landed a change in any open-source project at all. The first of their fixes shipped in Arc 26.09.1. The rest are already in the release notes for 26.09.2, the release we are sprinting on right now. All of them are credited in the README, and a few are already on their second and third PR.
This post is about how that happened, and an invitation to be number ten.
What changed
Nothing about Arc changed. What changed was that we started writing issues for people who don't know the codebase yet.
Over the last few months I noticed a wave of junior developers looking for their first open-source contribution. They were showing up on Discord and GitHub with the same question: "I want to help, where do I start?" And the honest answer was that we didn't have a good place to point them. Arc's issue tracker was full of things I knew how to fix but hadn't written down in a way anyone else could pick up.
So we started tagging issues with good first issue, and we changed how we wrote them. A good first issue in Arc now tells you:
- Which file and which line. You should not need to spelunk through a 100k-line Go codebase to find where the bug lives.
- What the failure mode is. What goes wrong, under what conditions, and how you would observe it.
- The intended shape of the fix. Not the code, but the approach. "Guard the nil handler before dispatch and add a regression test" is enough for someone to get going.
That's it. That is the entire trick. The people were always there. They needed a door with a sign on it.
Who showed up
Some of the changes that came in through that door, all from people contributing to Arc for the first time:
- @SAY-5 hardened the MQTT handlers and manager against nil dereferences, with regression coverage (commit).
- @mvanhorn fixed a backup/restore concurrency bug so competing operations get a clean 409 instead of silently queueing. That one shipped in 26.09.1.
- @bferanmi806-sketch landed a five-PR Iceberg reliability series, then came back for a compaction job-history retention fix.
- @Thundercloud12 fixed Azure not-found error detection so it survives joined multi-errors.
- @atirna made live SQLite backup and restore safe: VACUUM INTO snapshots, rename-swap restores, restart-required signaling.
Everything except the backup concurrency fix lands in 26.09.2.
None of these are toy changes. Backup safety, storage-backend error handling, and Iceberg metadata correctness are things people running Arc in production depend on. Every one of them was scoped small enough that a newcomer could own it end to end, and every one of them went through the same review as a change I would write myself.
What a mergeable PR looks like
We wrote all of this down in CONTRIBUTING.md, but here is the short version, because it is the difference between a PR that merges in a day and a PR that sits.
One issue per PR. Reference it in the body with Closes #123, or Refs #123 if you only cover part of it. Comment on the issue when you start so nobody duplicates your work.
Keep it small. We do not review large PRs. That is not a threat, it is a scheduling reality: a PR that does one thing can be verified in twenty minutes, and a PR that does five things needs an afternoon nobody has. If your fix is large, split it into a series that merges independently. Small PRs merge fast.
Add a test. A bug fix needs a regression test that fails before the fix and passes after it. Deterministic tests, please. Sleeps and retries are how flaky CI is born.
Add a release-notes entry. Fixes go into the current planned release notes file (right now that is RELEASE_NOTES_2026.09.2.md) as a ### entry under ## Bug fixes, ending with a credit line:
Contributed by [@your-handle](https://github.com/your-handle) in [#PR](https://github.com/Basekick-Labs/arc/pull/PR).Match the house style. Run gofmt and go vet. Reuse the patterns the surrounding code already uses. If the package logs with struct logger fields, don't introduce context-carried loggers. Consistency is worth more than your preference, and mine.
Leave "Allow edits by maintainers" on. We often resolve release-notes conflicts and small fixups directly on your branch so it merges without another round trip.
Write the title as a conventional commit. PRs are squash-merged with the title as the commit subject, so fix(mqtt): await unsubscribe tokens in Stop() is what ends up in history.
The review is strict. That is the point.
I want to be direct about this, because it is the part that scares people off and it shouldn't.
Arc is a database. People point Telegraf fleets at it, run it on submarines, and query billions of rows from it. A regression in a backup path or a query rewriter doesn't produce a wrong pixel, it produces wrong answers or lost data. So every PR gets reviewed the same way regardless of who wrote it or how experienced they are:
- CI must be green. First-time contributors need a maintainer to approve the workflow run, which usually happens at first review.
- Reviewers verify claims locally. If your PR says "tested on macOS, the test fails without the fix," we check that. Precise descriptions of what you ran and what you observed make this fast.
- Every line has to be defensible. If a reviewer asks why a line exists, there needs to be an answer.
Here is what that means for a junior developer: a round of review comments is not a rejection. It is the most concentrated feedback you will get on your code anywhere. In most jobs, nobody senior reads your diff line by line and tells you exactly what a nil guard is missing or why a test isn't deterministic. Here, that is the default. The contributors who came back for a third PR are the ones who treated the first review as the reason to do it.
We are strict with the code so we can be generous with the people.
On AI-assisted contributions
You can use AI tools. Most of us do. Two conditions:
Be strong on the logic. You are the author. You need to understand why the change is correct, what the failure mode was, and what the edge cases are. "The tool wrote it" is not an answer to a review question.
Review it yourself first. Read the whole diff. Run the tests. Cut anything you can't defend before you submit. Unverified AI output burns the review cycle that could have gone to your next contribution.
And the size rule applies double here. AI tools make it trivial to generate a 1,500-line diff. We will ask you to split it.
Building and testing
Arc is Go 1.26+. The DuckDB integration uses cgo, so the full suite needs a cgo-capable toolchain:
go build ./...
go test ./... # package tests
go test -tags=duckdb_arrow -race ./... # what CI runsIf your environment can't run the cgo packages (common on Windows), say so in the PR body and run what you can. Linux CI is the authoritative validation, and we verify locally before merging.
What you get
Your handle in the release notes. Your handle and name in the README's contributor list. A mention in the release blog post, the same way this post mentions the people above.
Less tangibly: a merged change in a database that ingests 34 million records per second, reviewed by people who care about it, that you can point to in your next interview and explain line by line. That last part is the one that matters.
Where to start
The good first issue queue is open right now. As I write this it has a documentation gap, a helper extraction with a regression test, two tiering cache bugs, a missing query timeout, and an MQTT shutdown race. Each one names the file, the line, and the shape of the fix.
Pick one. Comment that you're on it. Ask on the issue if the shape is unclear, or come find us on Discord.
And if Arc is useful to you, or you just enjoyed the process, star the repo ;)