Module 14: Contributing to PostgreSQL
PostgreSQL is one of the most welcoming open-source projects — and arguably the most technically rigorous. Unlike many open-source communities where a pull request can be merged by a single maintainer after a cursory review, PostgreSQL operates on a mailing-list-driven, consensus-based model that has produced one of the most stable and well-engineered codebases in the history of software. This module guides you through the contribution process, from finding issues to getting your first patch committed. It is not a quick weekend project — but neither is building a reputation as someone who can be trusted with infrastructure that runs the world’s financial systems, healthcare records, and government databases.Difficulty: Expert
Prerequisite: Module 13 (Source Code)
Outcome: First accepted contribution
14.1 PostgreSQL Community Structure
Think of the PostgreSQL community like a traditional guild system. You don’t walk in and start forging swords on day one. You apprentice, you prove yourself on small tasks, you earn trust over years. This is intentional — PostgreSQL stores data people cannot afford to lose, and the community treats that responsibility with the gravity it deserves.14.2 Types of Contributions
A common misconception is that “contributing to open source” means writing code. In PostgreSQL, some of the most impactful contributors are people who review patches, triage bugs, or improve documentation. The project has a perpetual shortage of reviewers — submitting a patch is easy compared to the expertise needed to evaluate someone else’s patch for correctness, edge cases, and long-term maintainability.Documentation
- Fix typos and unclear explanations
- Add examples to function documentation (many pg functions have zero examples)
- Translate to other languages
- Write tutorials and how-to guides
- Cross-reference related features that docs currently treat in isolation
Bug Reports
- Report bugs with minimal reproducible examples (a 5-line SQL script beats a paragraph of prose)
- Verify and triage existing bug reports (can you reproduce it on HEAD?)
- Test patches from others on your specific platform/configuration
- Write regression tests that capture the exact failure scenario
Code Patches
- Bug fixes (start small: off-by-one errors, edge cases in error handling)
- Performance improvements (always include benchmarks)
- New features (expect 3-6 months of review cycles for anything non-trivial)
- Code cleanup and refactoring (tread carefully — “cleanup” patches that change behavior are rejected)
Review
- Review patches in Commitfest (the backlog is always enormous)
- Test patches for correctness on your platform and configuration
- Provide constructive feedback with specific suggestions, not vague criticism
- Help with code archeology (git blame to explain why something is the way it is)
14.3 Finding Your First Contribution
Documentation Fixes
Documentation contributions are the “hello world” of PostgreSQL contribution — but that does not mean they lack impact. Many PostgreSQL functions are documented with formal syntax but zero practical examples. Adding a clear, correct example to a function that thousands of DBAs use daily is a genuine service.Good First Issues
TODO Items in Code
TODO Items in Code
git log to see if the surrounding code has been touched recently.Open Bugs
Open Bugs
Commitfest Needs Review
Commitfest Needs Review
Missing Tests
Missing Tests
14.4 Development Workflow
Step 1: Set Up Mailing List
The mailing list is not just a communication channel — it is the development platform. There is no GitHub Issues page, no Jira board, no Slack workspace. The mailing list is the system of record. Learning to navigate it effectively is as important as learning the code.Step 2: Create Your Patch
PostgreSQL usesgit format-patch, not pull requests. The generated .patch file is attached to your email to the mailing list. This means your commit message is your cover letter — it needs to be clear, complete, and self-contained.
Step 3: Test Thoroughly
This is where most first-time contributors underinvest. PostgreSQL reviewers will ask “did you run the full regression suite?” and they will test your patch themselves. If it fails tests you should have caught, you lose credibility that takes months to rebuild.--enable-cassert build is non-negotiable for serious contributions. It enables hundreds of internal consistency checks (Assert macros) that are compiled out in production builds. Many subtle bugs — dangling pointers, incorrect catalog state, missed lock acquisitions — are only caught with cassert enabled. If your patch passes make check but fails with cassert, you have a real bug.14.5 Patch Submission
Email Format
Commitfest Registration
14.6 Responding to Feedback
Common Review Comments
- Code Style
- Missing Tests
- Documentation
- Design Questions
Updating Your Patch
Patch versioning is crucial in the PostgreSQL workflow. Reviewers track versions (v1, v2, v3…) and expect each new version to address all prior feedback. Submitting a v3 that ignores a comment from the v1 review is a quick way to lose reviewer goodwill.14.7 Patch Lifecycle
The lifecycle below looks straightforward, but the reality is messier. A patch might bounce between “Needs Review” and “Waiting on Author” five or six times over multiple Commitfests. This is normal — it means the community is taking your patch seriously enough to invest review time. The patches that get rejected outright are often the ones that were never reviewed at all, which typically means they were either too large to review or too poorly motivated to attract interest.14.8 Community Etiquette
The PostgreSQL community is famously direct. Reviews can feel blunt if you come from environments where feedback is heavily softened. A reviewer saying “This approach is wrong because X” is not being rude — they are respecting your time by being clear. The harshest feedback is often from the people who care most about the project.Do’s
- Be patient: Reviews take time; contributors are volunteers with day jobs
- Be grateful: Thank reviewers, even for criticism — they spent their unpaid time on your code
- Be thorough: Complete patches (code + tests + docs) save everyone time and signal professionalism
- Be responsive: Reply within a few days; stale patches get deprioritized
- Be humble: Even 20-year PostgreSQL veterans learn from review — so will you
- Research first: Search the mailing list archives before asking; your question may have a detailed answer from 2009 that is still perfectly relevant
- Address every point: If a reviewer raises 5 issues, respond to all 5, even if just to say “agreed, fixed in v2”
Don’ts
- Don’t ping repeatedly: One polite follow-up after 2-3 weeks is appropriate. More than that and you are the person nobody wants to review
- Don’t argue endlessly: State your technical case clearly, once. If consensus goes against you, accept it gracefully. You can always propose it again in a future release cycle with new evidence
- Don’t take criticism personally: “This code is incorrect” is about the code, not about you. The separation matters
- Don’t abandon patches: If life intervenes, email the list saying you are withdrawing the patch. Abandoned patches waste reviewer time and clog the Commitfest queue
- Don’t submit massive patches: A 5,000-line patch is a review burden. Break it into logical, independently-reviewable pieces — even if the pieces only make sense together
- Don’t ignore feedback: Submitting v2 without addressing v1 review comments is the fastest way to get your patch permanently ignored
Sample Interactions
Good Response Example
Good Response Example
14.9 Building Your Reputation
Progression Path
Getting Recognized
- Conference talks: Submit to PGConf, PGDay events. A talk titled “How I fixed my first PostgreSQL bug” is compelling because it is authentic and approachable.
- Blog posts: Write about your contribution journey. Document the hard parts — the confusion, the failed attempts, the reviewer feedback that stung but made you better. Honesty resonates more than polished narratives.
- PostgreSQL Weekly: Get your patches mentioned in community newsletters. The visibility compounds over time.
- Review consistently: Reviewers are the scarcest resource in the community. A person who reviews 20 patches per Commitfest becomes known faster than someone who submits 5 patches.
- Mentor others: Help newcomers navigate the process you just learned. The community notices people who invest in its growth.
14.10 Practice: Your First Contribution
Find a Documentation Issue
doc/src/sgml/ for unclear function documentation.
Pick one function you understand well.Improve the Documentation
Test Your Changes
Create and Submit Patch
Register in Commitfest
14.11 Resources
Developer FAQ
Submitting a Patch
Reviewing a Patch
Code Style
Interview Deep-Dive
You say you have contributed to PostgreSQL. Walk me through the lifecycle of your patch -- from identifying the problem to getting it committed. What was the hardest part?
You say you have contributed to PostgreSQL. Walk me through the lifecycle of your patch -- from identifying the problem to getting it committed. What was the hardest part?
json_populate_record function — the docs described the syntax but had no example showing how it handles nested JSON objects with NULL fields, which is a common source of confusion based on questions I saw on pgsql-general. I cloned the repository, found the relevant SGML file at doc/src/sgml/func.sgml, and added three examples covering the basic case, the nested-object case, and the NULL-handling edge case.Before submitting, I built the docs locally with make html to verify rendering, ran make check to ensure I had not broken anything, and searched the pgsql-hackers archives to confirm no one had already submitted a similar patch. I generated the patch with git format-patch, wrote a cover email explaining the motivation (linking to two pgsql-general threads where users were confused), and sent it to pgsql-hackers with [PATCH] in the subject line. I registered it in the current Commitfest.The hardest part was the review cycle. My first version was returned with feedback that my examples used features from a newer PostgreSQL version than what the docs target. I had to rewrite the examples to work with the minimum supported version. The second version got a style comment about SGML formatting conventions I had not known about. The third version was accepted. Total elapsed time: about 6 weeks from submission to commit.The non-obvious lesson: even a documentation patch goes through rigorous review. This is why PostgreSQL’s docs are considered the gold standard. The bar is high because the output quality matters — millions of developers read those docs.Follow-up: If you wanted to contribute a code patch to the query optimizer, how would you approach it differently than a documentation patch?The stakes and process are fundamentally different. For a code patch to the optimizer, I would start by spending 2-4 weeks reading the existing code and relevant mailing list discussions to understand the current design philosophy. Before writing any code, I would send an email to pgsql-hackers proposing the change conceptually and asking for design feedback — this avoids investing weeks in an implementation that the community will reject on design grounds. The patch itself would need to include regression tests (not optional for code changes), pass make check under --enable-cassert (assertion-heavy mode), and include performance benchmarks showing the improvement. I would expect 3-6 review cycles spanning multiple Commitfests, and I would need to rebase my patch as other changes land on master. The optimizer is one of the most actively developed subsystems, so merge conflicts are frequent and must be resolved promptly to avoid losing reviewer momentum.How does the PostgreSQL development process compare to a typical GitHub-based open-source project? What are the trade-offs of mailing-list-driven development?
How does the PostgreSQL development process compare to a typical GitHub-based open-source project? What are the trade-offs of mailing-list-driven development?
You are reviewing a patch in the PostgreSQL Commitfest that adds a new aggregate function. What specific things would you check, and in what order?
You are reviewing a patch in the PostgreSQL Commitfest that adds a new aggregate function. What specific things would you check, and in what order?
CREATE AGGREGATE infrastructure, that the state transition function and final function are correctly separated, and that the function handles NULL inputs correctly (most aggregate bugs live in NULL handling). I would also check whether the function could be implemented as a combination of existing functions — adding a new aggregate to core PostgreSQL is a maintenance commitment forever, so it needs to justify its existence.Third, correctness: I would read the C implementation of the state transition function and final function line by line. Key things to check: memory context management (is the aggregate state allocated in the right context so it survives across rows but is freed after the query?), overflow handling for numeric types, and correct behavior for edge cases (empty input, single row, all NULLs). I would also verify that the implementation matches the documented behavior exactly.Fourth, testing: Does the patch include regression tests? Do the tests cover the happy path, NULL inputs, empty input, overflow, and interaction with GROUP BY, HAVING, window functions, and DISTINCT? A common gap: the patch tests the function in isolation but not in combination with other SQL features. I would also check that the expected output file matches actual output by running make check.Fifth, documentation: Is the new function documented in doc/src/sgml/func.sgml? Does the documentation include at least one example? Is the function listed in the appropriate section alongside related aggregates?I would write my review as a reply to the pgsql-hackers thread, organizing feedback by severity: blockers (must fix), suggestions (should consider), and nits (style issues that do not block commit). I would explicitly state my assessment: “Needs revision,” “Ready for committer,” or “Reject” with rationale.Follow-up: The patch author pushes back on one of your review comments, arguing their approach is correct. How do you handle the disagreement?I re-examine my own reasoning first. If I am wrong, I say so immediately and retract the comment — there is no shame in being corrected, and it builds trust. If I still believe I am right, I present a concrete example or test case that demonstrates the problem, rather than arguing in the abstract. If we are genuinely at an impasse on a design question (not a correctness question), I would say “I think this is worth getting more eyes on” and invite other hackers to weigh in. The mailing-list model is designed for exactly this kind of deliberation. I would never block a patch over a matter of taste — only over correctness, safety, or clear precedent violations.How would you evaluate whether a specific feature should be contributed to PostgreSQL core versus maintained as an extension? What criteria would you use?
How would you evaluate whether a specific feature should be contributed to PostgreSQL core versus maintained as an extension? What criteria would you use?
pg_stat_statements, which started as a contrib module) began life as extensions. If your feature has been used in production by multiple organizations as an extension and the community agrees it should be universally available, the path to core is much smoother.Fifth, compatibility guarantees. Core PostgreSQL makes strong backward compatibility promises. Adding a new SQL function to core means that function name is reserved forever. Adding a new GUC (configuration parameter) means it must be supported across major version upgrades. Extensions have more flexibility to break compatibility between versions.My recommendation for any new contributor: start as an extension. It lets you iterate faster, prove the value with real users, and build a track record. If the community later agrees it belongs in core, the existing extension becomes the strongest possible evidence for your proposal.Follow-up: You have built a popular extension with 5,000 GitHub stars. The community is split on whether to bring it into core. How do you navigate that disagreement?I would write a formal proposal email to pgsql-hackers with three sections: (1) the evidence for inclusion — user adoption numbers, performance characteristics, the specific limitation of the extension API that makes core inclusion beneficial; (2) the maintenance commitment I am personally willing to make — because proposing a feature for core without volunteering to maintain it is disrespectful of the committer team’s time; and (3) an honest assessment of the arguments against inclusion, showing that I have genuinely considered the opposing view. Then I would let the thread run, participate in discussion without being defensive, and accept the outcome. If the consensus is “keep it as an extension,” that is a valid answer. Popularity is not sufficient justification — it must also meet the technical criteria. Many of the most successful PostgreSQL ecosystem tools (pgBouncer, pg_repack, Citus before acquisition) thrived as external projects without ever entering core.Congratulations!
You’re now ready to contribute to PostgreSQL. Remember:- Start small: Documentation and bug reports are valuable — they are not “lesser” contributions
- Be patient: The process takes time but the skills you build (reading unfamiliar C, navigating a large codebase, communicating technical ideas in writing) are career-defining
- Stay engaged: Consistency matters more than size — one patch per Commitfest for two years builds a reputation
- Have fun: You’re improving a project used by millions, and you’re joining a community of some of the best database engineers in the world