Summary
- Kamp, widely known as PHK, designed and wrote the original Varnish Cache after Verdens Gang commissioned a production web accelerator, using operating-system virtual memory instead of a second application-level cache manager.
- His FreeBSD work across releases, jails, GEOM, timecounter and base-system primitives reflects a consistent discipline: put state in a reusable layer with explicit ownership and failure boundaries.
- VCL, process separation and shared-memory logging keep Varnish’s request path narrow, while shifting greater responsibility to HTTP policy, kernel behaviour, extensions and surrounding delivery systems.
- Beer-Ware, the Moral License and sponsorship experiments expose the economic counterpart to technical minimalism: machine work can be removed while security, releases and specialised human maintenance still need funding.
Verdens Gang gave performance by subtraction a production test
Varnish Cache began around 2005 with a production problem at the Norwegian newspaper Verdens Gang. The publisher needed a web accelerator that could absorb traffic bursts and reduce backend work without reproducing the complexity and bottlenecks of existing cache software. Poul-Henning Kamp designed and wrote the initial system with VG’s support, and the project became publicly available in 2006.
The decisive choice was to remove an application-level cache manager. Varnish mapped cached objects into an address space and allowed the operating system’s virtual-memory system to decide which pages remained resident. The application concentrated on HTTP policy, request handling and object metadata. VCL expressed cache decisions; a management process controlled configuration and worker lifecycle; a shared-memory log kept high-volume observation away from synchronous request writes.
Those choices earned a reputation for speed, but their deeper effect was to relocate responsibility. Kernel memory behaviour became more consequential. Compiled policy became both powerful and dangerous. A focused proxy needed adjacent systems for functions outside its scope. Performance by subtraction did not make the total system simple; it made the owners of state more explicit.
Kamp had developed that instinct through FreeBSD release engineering, jails, GEOM, timecounter and other kernel or base-system primitives. His later work on precision timekeeping, open-source funding and project governance applies the same test to code and institutions: which layer already owns the job, and what dependency is created when another layer is removed?
The governing question is whether doing less produces a system that is easier to operate and transfer, or simply moves complexity where the operator can no longer see it. Kamp’s record is strongest when the subtraction leaves a clear interface, observable failure path and maintainer prepared to carry the remaining obligation.
Release engineering made interface promises visible
Kamp became involved with the code lineage around 386BSD and FreeBSD before the project’s governance and architecture had fully settled. His own historical account places him on the FreeBSD core team from early 1994 for roughly six years and describes responsibility for FreeBSD 2.x release engineering along with work across the kernel and base system.
Release engineering is an important starting point because it forces a developer to see the operating system as a deliverable rather than a collection of patches. Code has to build together, upgrades have to be possible and failures have to be understood by users who did not follow the development discussion. The release engineer works at the boundary between technical ambition and the system people can actually install.
Kamp’s contribution list includes VFS name-cache work, sysctl, memory allocation, device systems, safe-string buffers, jails, GEOM, disk encryption and timecounter. The list comes partly from his first-person archive and should not replace commit-level attribution. Many of these systems were developed with others and maintained extensively after his original work. The breadth is still well supported as a description of the design environment from which Varnish emerged.
An operating-system project rewards mechanisms that can be reused by unrelated applications. A name cache improves path lookup across the system. A timecounter creates a common abstraction for hardware clocks. GEOM lets storage transformations compose. Jails expose an isolation model rather than packaging one hosted service. This orientation encourages the question Kamp later asked in Varnish: can the application rely on a general kernel mechanism instead of reimplementing it?
FreeBSD also provided governance experience. Kamp served on an early core team and left that formal role as the project moved to an elected model around 2000. His technical involvement continued, but current FreeBSD authority belongs to present committers and the current Core Team. Historical leadership is not a continuing corporate title.
That distinction matters because open-source influence can persist after formal office ends. A subsystem can encode an architect’s choices for decades, while later maintainers alter implementation and policy. The durable contribution is a usable abstraction that others can own, not an indefinite right of control.
The breadth of Kamp’s FreeBSD record can look like a catalogue of unrelated kernel work until release engineering is placed at the centre. A release is where local changes become one operating system. Every subsystem has to build against the same interfaces, installation media has to reach users, defaults have to be defensible and changes have to survive an upgrade from an older state.
Kamp’s historical responsibility for FreeBSD 2.x therefore matters beyond the version numbers. Release work exposes dependencies that individual developers can ignore when looking only at their own code. A device change can break an installer. A library interface can strand third-party software. A new kernel mechanism can be technically sound and operationally unusable if documentation, tooling and rollback are missing.
This background helps explain the later shape of Varnish. The cache was not designed as a paper algorithm awaiting an implementation team. It emerged as software that a publisher needed to run, observe and change. The management process, VCL loading, shared log and runtime parameters were part of the system because a fast loop without an operating path would not solve Verdens Gang’s problem.
Release engineering also encourages resistance to permanent compatibility liabilities. Once an interface is published and users build around it, removal becomes costly. The safest place to reject a weak abstraction is before it becomes part of a release. Kamp’s writing often favours narrow contracts and explicit ownership because every extra surface eventually becomes somebody’s maintenance obligation.
The evidence does not support assigning every FreeBSD 2.x release decision to one person. It does support a period in which Kamp worked at the integration boundary. That role supplied a practical lesson: architecture is partly the accumulation of promises that users expect the next release to honour.
For infrastructure buyers, this is a useful distinction between a prototype and a maintained system. The prototype demonstrates a mechanism. The release process demonstrates that maintainers can package the mechanism, communicate its limits, repair regressions and carry users forward. Varnish’s longevity depends on the second discipline as much as on the original storage design.
Small primitives carried both long value and dated assumptions
Several of Kamp’s FreeBSD contributions were not products an operator would purchase or even notice. They were base-system primitives: name-cache work, memory allocation, sysctl, dynamic string construction and device infrastructure. Their value came from changing the cost or safety of work performed by other code.
A VFS name cache avoids repeating expensive path-resolution work when the same filesystem names are used again. The precise implementation has evolved, and credit is collective, but the design problem is durable. File paths are a human-readable namespace laid over storage objects. Caching the relationship can improve system-wide performance, while stale or incorrectly invalidated entries can corrupt the view of the filesystem. It is a compact example of the same bargain later visible in HTTP caching: reuse is valuable only when the rules for invalidation are correct.
phkmalloc, Kamp’s historical allocator work, addressed another common cost. General-purpose allocation sits beneath almost every service, and allocator behaviour affects fragmentation, locking and locality. The historical implementation should not be presented as the current answer for all systems. Its relevance is that performance work often begins below the feature being measured. A web cache can be limited by allocation and object lifetime even when its HTTP logic is efficient.
The sbuf work supplied safer dynamic string construction in kernel and base-system code. Strings built from partial data are a routine source of truncation and memory errors. A shared primitive does not make all callers correct, but it reduces the need for each subsystem to improvise buffer management. This is the quieter form of systems engineering: remove one repeated source of error from many future call sites.
Device and DEVFS work dealt with how hardware appears to software. Devices are physical or virtual resources with lifetime, naming and permission concerns. A coherent namespace and attachment model allows later drivers and administrative tools to reason about them without each inventing a private convention.
These contributions should not be stretched into a claim that Kamp alone designed FreeBSD’s modern base system. His own archive is first-person evidence, and later developers performed extensive work. The defensible conclusion is about method. He repeatedly worked on interfaces whose benefit was multiplied by the number of callers above them.
That multiplication is easy to miss in conventional profiles because no customer logo identifies who benefited from a safer string primitive or a more predictable clock abstraction. Infrastructure value often appears as the absence of duplicated code, avoidable crashes or repeated I/O. The work becomes visible only when the primitive fails or has to be replaced.
Kamp’s record includes GBDE disk encryption and the password-hash format commonly called MD5crypt. Both belong in a complete account of his systems work, and both require firm historical boundaries.
GBDE applied cryptographic transformation within FreeBSD storage. It fits the GEOM-era concern with composing functions around block devices, although current FreeBSD users have other options and current security recommendations depend on threat model, implementation and support. An early encryption design is evidence of work on confidentiality and key-dependent storage, not evidence that the historical mechanism should be selected for a new deployment.
MD5crypt was designed for password storage in a period when plain fast MD5 hashing needed strengthening through a format with salt and repeated work. The format spread across Unix-like systems and network equipment. Modern password security has moved toward deliberately expensive, memory-aware password hashing because cheap general-purpose hashes are vulnerable to large-scale guessing. The correct editorial treatment is influence with expiration: a design can improve the state of practice in one period and later become unsuitable.
This dating discipline is especially important in infrastructure journalism. Old software persists in appliances and embedded products long after guidance changes. Calling a mechanism “widely deployed” can sound like a recommendation when it may instead describe technical debt. Crediting an author does not transfer responsibility for every later vendor decision to keep using it.
The principle also applies to Varnish configurations, FreeBSD subsystems and time protocols. A feature name can remain stable while implementation and threat assumptions change. Profiles should separate the original problem, the historical contribution, current maintenance and present deployment advice.
Kamp’s willingness to revisit old systems in essays and computer-history work makes that separation part of the subject rather than an editorial inconvenience. Systems engineers inherit their own past decisions. A mature practice records why a choice was reasonable, what changed and how users can migrate without pretending the earlier work never mattered.
Jails made isolation a kernel primitive rather than an application convention
FreeBSD jails extended process isolation beyond the traditional chroot model by combining filesystem, process, network and administrative restrictions. The idea allowed multiple service environments to share one kernel while seeing constrained views of the system.
Kamp’s early contribution is part of the documented history, and later jail development belongs to a much wider FreeBSD community. The distinction is especially important because jails evolved into a large operational feature set. A founder can establish the model without being responsible for every later security boundary, management tool or deployment.
The architectural relevance is clear. Isolation is more reliable when the kernel enforces it than when each application agrees to behave. A jailed process can be restricted from seeing other process groups or network resources, subject to the configuration and the shared-kernel threat model. Operators can run services with reduced blast radius and lower overhead than separate physical machines.
A jail is not a guarantee against every escape or kernel vulnerability. The environments share one kernel. Privileged configuration and device exposure matter. Network design can undermine isolation. The mechanism reduces authority and creates a clearer boundary; it does not eliminate the need for security engineering.
That reasoning reappears in Varnish’s management and worker split. A child process handling traffic does not need every management privilege. The parent can restart it and control configuration. Process boundaries assign failure consequences instead of assuming one large process will remain correct.
Jails also show the economic value of a primitive. Hosting providers and systems administrators can build services around isolation without each inventing a private mechanism. The kernel project absorbs the cost of maintaining the boundary, and users inherit both its benefits and its bugs. That transfer is acceptable when ownership and update paths are clear.
GEOM treated storage as a graph of composable transformations
Storage systems frequently layer functions: a disk may be partitioned, mirrored, encrypted, labelled and exposed through another abstraction. Without a coherent framework, each feature can contain its own device-discovery and I/O plumbing, creating duplication and difficult interactions.
GEOM provided FreeBSD with a modular framework for composing storage transformations. Providers and consumers connect in a graph, allowing classes to implement operations such as partitioning, mirroring or encryption. The framework gives the kernel a common language for how storage layers attach and pass I/O.
Kamp is documented as a major architect and contributor. Later GEOM classes and maintenance belong to the project. The significance is again a mechanism rather than a complete product: define the contracts so several functions can coexist without every one becoming a private stack.
Composition has costs. Each layer can add metadata, failure behaviour and recovery requirements. An encryption layer needs keys; a mirror needs state reconciliation; a partition layer has its own geometry. A graph that is elegant in code can be difficult to repair when an underlying device fails and the operator does not understand the order of transformations.
GEOM therefore reflects both sides of Kamp’s systems philosophy. Clear interfaces reduce duplicated implementation. They do not excuse operators from understanding the system assembled from those interfaces. A generic primitive can make more combinations possible than any one team can test.
The comparison with Varnish is not that web caching and block I/O are the same. It is that both systems ask which layer should own state and how transformations should be composed without copying or hiding more than necessary. Kamp’s work across the kernel gave him practical confidence in operating-system abstractions that application developers often avoid.
Timecounter made clocks a system responsibility
Reliable time inside an operating system sounds simple until hardware clocks disagree, drift, stop or offer different resolution and stability. Applications want a monotonic, accurate timescale; the kernel has to combine hardware sources and correction mechanisms without making every subsystem understand oscillator behaviour.
FreeBSD’s timecounter work created an abstraction over hardware time sources. Kamp’s contribution belongs to a broader history of kernel timekeeping and later maintenance. The model allowed the system to select and use counters according to quality while exposing time to the rest of the operating system through a common interface.
This work led into Kamp’s long-running interest in NTP, PTP, hardware references and the weaknesses of legacy time protocols. Time infrastructure combines oscillators, network delay, kernel discipline and operational monitoring. A protocol message can be correct while the local clock is unstable. A high-resolution counter can be precise and inaccurate. A network path can introduce asymmetric delay that a simple round-trip estimate cannot remove.
Timekeeping appears far removed from HTTP caching, but the architectural question is similar. Which layer should own correction? What state is authoritative? How can the system expose uncertainty rather than one misleading number? Duplicating time logic in every application would be worse than maintaining a strong kernel and protocol boundary.
The operational stakes are high. Logs, distributed transactions, certificates and measurement depend on time. An error can make events appear out of order or invalidate security decisions. The infrastructure deserves independent monitoring and fallback rather than blind trust in one server.
Kamp’s recent writing and experimental work continue to treat time as a systems problem. The public record establishes sustained interest, not a claim that one implementation replaced NTP or PTP. The value lies in insisting that time be engineered from hardware through protocol and kernel rather than accepted as a utility with no owner.
Kamp’s work on timecounter, NTP, PTP experiments and timing hardware forms a second technical pillar beside Varnish. Time may look like a service the operating system can obtain once and distribute. In practice, a machine combines an imperfect oscillator, hardware counters, interrupt and scheduling delay, kernel conversion, synchronisation protocols and applications with different tolerance for error.
The FreeBSD timecounter abstraction allows the kernel to obtain time from available hardware sources through a common interface. A counter can have high frequency, limited width, drift, rollover behaviour or platform-specific access costs. The kernel has to convert those ticks into a useful timebase and choose among sources without allowing a device quirk to leak into every application.
This is another case of placing state at the right layer. Applications should not each read hardware counters and invent correction. The kernel is positioned to maintain a coherent system clock and expose it through common interfaces. Network protocols can estimate offset and frequency against external references. Monitoring can then detect when the local clock or reference path has become unreliable.
NTP and PTP solve related but different operational problems. NTP distributes time across general networks and must tolerate variable delay and imperfect servers. PTP can provide much tighter synchronisation in controlled environments with hardware timestamping and network support. Neither protocol can repeal oscillator physics, path asymmetry or bad operational design.
Kamp’s critiques of legacy protocol and implementation choices should be treated as technical argument, not automatic consensus. Their significance lies in making the hidden chain explicit. A timestamp in a log or packet capture is the output of hardware, kernel and protocol decisions. When those layers disagree, distributed systems can misorder events, invalidate certificates, corrupt measurements or make incident reconstruction unreliable.
The connection to Varnish is not that web caches require laboratory-grade clocks. It is the recurring insistence that one layer must own measurement and expose enough evidence for the rest of the system to trust it. A cache lifetime, a log timestamp and a timeout are all decisions about time. If the clock is unstable or its uncertainty hidden, higher-level correctness becomes difficult to prove.
Precision-time work also illustrates the limits of independent engineering. Building a reference or experimental daemon can reveal protocol problems, but production time service depends on hardware supply, network topology, kernel integration, long observation and operators who respond to drift. No single implementation controls that chain.
A customer-funded project turned architecture into an open product
The commissioning relationship is central. Varnish was not invented to win a synthetic contest. It had a customer, a workload and operational feedback. A news publisher has traffic bursts, frequently changing content and backend systems whose latency matters under demand. The cache has to serve objects quickly and avoid serving the wrong object.
The initial funding also illustrates how open infrastructure can begin. A customer pays to solve a concrete problem, and the resulting code is released for wider use. The community can test other workloads and improve the system. The sponsor gains a solution without necessarily owning a closed product.
Public evidence does not disclose the full contract value or terms. It supports the origin and production relationship, not a financial estimate. VG’s role should not be converted into current ownership of Varnish, just as Kamp’s authorship should not be converted into ownership of every deployment.
The decision to start a new cache rather than extend an existing one reflected architectural judgement. Kamp believed that conventional approaches carried assumptions from older operating systems and duplicated kernel caching. A clean design could take advantage of modern virtual memory and a narrow HTTP acceleration scope.
Starting over also creates risk. Mature projects contain years of protocol edge cases. A new implementation has to learn them through testing and incidents. The production sponsor supplied an environment in which those assumptions could be confronted early.
Virtual memory became the cache manager
Varnish’s defining storage choice was to use memory mapping and allow the operating system to manage page residency. Cached objects could be represented in an address space, while the kernel decided which pages stayed in RAM and which were reclaimed or backed by storage.
The design avoided a second cache-replacement system inside the application. A traditional cache might track objects in memory, write them to files and later read them through the kernel’s page cache, creating copies and duplicated state. Varnish could refer to mapped data and let page faults or eviction reflect the operating system’s global memory decisions.
This is sometimes summarised as Varnish being an in-memory cache. The phrase is incomplete. The architecture can use storage backed by files or memory, and the operating system may move pages according to pressure. Disk is not absent. It is managed through virtual-memory behaviour rather than through a user-space object I/O engine in the conventional form.
The approach depends on the kernel. Page replacement, writeback, filesystem behaviour and address-space limits affect performance. Memory pressure from unrelated processes can change residency. A container or virtual machine may have limits that interact with the host. Operators need system-level observability rather than only cache hit rates.
The gain is reduced work in the request path. Objects do not have to be copied through several buffers or read synchronously by application logic every time they are reused. The CPU can spend more time on HTTP decisions and network I/O.
The design is also a statement about trust. Kamp trusted a mature virtual-memory system to perform a task application developers often reimplement. That trust was informed by kernel experience. It is not a universal rule that every application should delegate storage. Workloads with different durability, access or control requirements may need another design.
Varnish’s performance reputation should therefore be stated within a workload. Cacheability, object size, backend latency, request mix, memory, kernel and configuration all matter. A benchmark proves behaviour in its test envelope, not permanent superiority to every proxy or CDN.
Varnish’s memory-mapped design is easiest to misunderstand when virtual address space is treated as a statement about physical RAM. Mapping an object gives the process an address through which the kernel can provide the page. It does not require every mapped page to remain resident at the same time.
This distinction made large address spaces useful. The application could refer to a cache larger than immediately resident memory, while the operating system decided which pages were active. On systems with constrained address space, the number and size of mappings could become a limit even before physical storage was exhausted.
Resident-set size is therefore only one part of capacity analysis. Operators need to understand mapped storage, page faults, reclaim, filesystem backing and pressure from other processes. A container limit can change the effective behaviour even when the host has free memory. Swapping or heavy fault activity can preserve correctness and destroy latency.
The architecture avoids an application-level eviction engine and does not remove eviction. It moves the decision into kernel policy, where Varnish has less direct control and benefits from system-wide knowledge. That trade works best when the operating system is trusted and the host is provisioned as one system rather than as isolated application quotas with hidden interactions.
This is a precise example of Kamp’s method. A duplicated cache manager was removed. The remaining layer became more important and had to be observed with the right metrics. “Varnish uses memory” is an incomplete operational statement; the useful question is how virtual memory supplies the working set under pressure.
VCL made cache policy executable—and reviewable
A cache cannot decide correctness from status codes alone. It needs rules for cookies, authentication, request methods, headers, backend selection, freshness, invalidation and exceptions. Varnish Configuration Language exposes those decisions to the operator.
VCL is translated into C and compiled into a loadable object. The running system can load configurations and switch among them under management control. Compiled policy avoids interpreting a high-level language for every request and gives operators a structured way to alter behaviour without modifying the daemon’s source.
The power is substantial. A VCL program can choose a backend, modify headers, decide whether a request may be cached, set time-to-live values, implement purging and direct traffic according to conditions. It becomes part of the application architecture even when maintained by an infrastructure team.
That power creates risk. A syntactically valid policy can cache personalised content, ignore authentication or send traffic to the wrong backend. A rule can improve hit rate and violate correctness. Changes need version control, tests, staged rollout and review by people who understand both HTTP and the application.
Compilation adds a trust boundary. The process invoking the compiler, module paths and any inline or extended code have to be controlled. VMODs can add capabilities and attack surface. A fast policy language is not automatically a safe one.
VCL also changes organisational responsibility. Application teams control cache headers; platform teams control VCL; security teams care about cookies and authentication. An incident can arise from an assumption between those teams. The language makes the policy explicit enough to review, but it cannot reconcile ownership by itself.
This is one of Kamp’s most consequential design choices. Performance is not hard-coded into one product configuration. Operators can express policy close to the request path. The system remains useful across different applications because the mechanism and the local decision are separated.
A reverse proxy cache can reduce backend load and latency only when it serves the correct representation to the correct requester. HTTP contains metadata intended to support this decision, and real applications frequently produce ambiguous or inconsistent signals.
Freshness can be controlled through cache directives and expiry times. Vary indicates that different request headers produce different representations. Cookies and authorisation often imply personalisation. A response may be safe to serve stale during backend failure and unsafe to reuse after a user change.
Varnish exposes these decisions rather than claiming that every successful response is cacheable. The operator can adjust policy and assumes responsibility for the result. A high hit rate achieved by ignoring Vary or authentication is a data-integrity failure, not a performance success.
Invalidation is another difficult boundary. Purging an object by URL may not remove all variants. Ban rules can match groups and consume resources. Application events can be delayed or lost. Short freshness periods reduce stale risk and backend savings. There is no universal invalidation strategy.
Backend behaviour also shapes the cache. Slow or failing origins create queues and retries. Serving stale content can preserve service, subject to policy. Health checks can remove a backend and can amplify failure if configured badly. Varnish is one layer in a delivery system whose correctness depends on the application and origin infrastructure.
The architectural discipline is to make these trade-offs explicit in policy and observability. Varnish can be fast because it avoids work, but it must never avoid the work required to determine whether reuse is valid.
The fast path stayed separate from control, observation and capacity limits
Varnish uses a management process and a worker or cache process. The management side controls configuration, parameters and child lifecycle. The worker handles traffic. If the child fails, the parent can collect information and restart it.
The split reduces the authority and persistence of the traffic-handling process. A crash does not require the management layer to disappear. New VCL can be compiled and loaded under controlled conditions. Privilege can be reduced after startup according to platform and configuration.
Restart is not recovery from every failure. In-memory state can be lost. Clients may see errors. A repeated crash can create a loop. The backend or operating system may be the actual cause. Operators need crash diagnostics and limits rather than treating automatic restart as proof of resilience.
The separation also supports upgrades and configuration transitions, but high availability belongs to the larger architecture. Multiple instances, load balancers, health checks and capacity are usually required if one Varnish process cannot be a single point of failure.
The pattern resembles Kamp’s kernel work: define a boundary so one component can fail without possessing every system privilege. The value is practical containment, not perfect isolation.
Varnish Shared Log writes structured event records into shared memory. Tools can read request, backend and cache transactions without forcing the worker to synchronously append every event to a conventional file.
This design reduces blocking and allows different consumers to inspect the same stream. Operators can trace a request, aggregate metrics or export logs into another system. The high-volume record remains close to the process while long-term storage is delegated.
Shared memory is finite. Consumers that fall behind can miss records as the ring advances. A tool used for incident investigation should export or retain the necessary data rather than assume the live log is an archive.
The event model is specialised. A transaction can involve client and backend requests, retries and cache decisions. Understanding the record requires familiarity with Varnish identifiers and lifecycle. Structured logging improves machine processing and does not eliminate the need for a schema.
Privacy and security apply. Headers, URLs and backend information can contain sensitive data. Exporters should minimise fields and control access. Fast logging can create a large volume whose storage cost exceeds the cache’s own resource use.
The architecture again removes work from the critical path and moves responsibility elsewhere. Varnish exposes detailed evidence efficiently; the operator owns retention, search and access policy.
Varnish’s worker model uses threads and pools to handle many concurrent connections. A thread can block on some operations without stopping all traffic, while the system controls creation and resource limits.
Threads consume stacks and scheduler attention. Too few can queue clients; too many can exhaust memory or increase contention. Slow clients and slow backends hold resources differently. Connection behaviour, keep-alive, timeouts and operating-system limits all affect the safe range.
The implementation has evolved, and exact tuning belongs to the deployed version. The general point is that concurrency does not become free because the cache is fast. Operators have to monitor thread queues, drops, backend latency and memory pressure.
A workload with cache hits in memory differs from one that repeatedly misses and waits on an origin. A benchmark dominated by hits says little about failure behaviour when the backend slows. Capacity planning should include miss storms, purges and restart scenarios.
Varnish’s narrow data path gives operators clear counters and controls. It also exposes the reality that performance is a system property: kernel networking, scheduler, memory, storage, backend and application policy all participate.
Open code, commercial support and voluntary funding remain separate layers
Varnish Cache is an open-source project with current maintainers, releases, packages and modules. Varnish Software is a separate commercial company offering products and services around the technology. Kamp is the original architect and remains associated with the project, while he does not own or control every current decision or commercial offering.
The distinction became more important as adoption expanded. Enterprises wanted support, packaged features and accountability. A company can supply those services and develop proprietary or separately governed components. The upstream project maintains a public code base and community process.
Commercial activity can support open development and create divergent incentives. Customers may request features unsuitable for the core. A company may carry more engineering capacity than unaffiliated maintainers. Trademarks and product names can confuse users about which layer they are buying.
A defensible profile credits Kamp for the architecture and initial implementation, credits current maintainers for ongoing releases and treats Varnish Software’s business as its own institutional record. Deployment claims from one layer should not be assigned to another.
The principle also applies to FreeBSD. Kamp’s historical core-team and subsystem work is significant; the current project is governed by present structures. Open infrastructure becomes durable when authorship can be honoured without becoming permanent ownership.
Kamp is associated with the Beer-Ware License, an informal permissive text that allows use and suggests buying the author a beer if the parties meet. The licence expresses social reciprocity in deliberately plain language. Its legal suitability depends on context, and organisations with formal compliance requirements may prefer conventional licences.
The Varnish Moral License addresses a different problem. It is a voluntary mechanism through which organisations benefiting from Varnish can support Kamp’s work. It is not the software licence and is not required to use the code. The “moral” framing asks users to recognise maintenance labour that a permissive legal licence cannot compel them to fund.
Kamp had earlier experimented with direct community sponsorship for FreeBSD work in 2004. The pattern shows sustained concern with the economics of infrastructure maintenance. Widely used code can generate substantial value while the people responsible for difficult, non-feature work receive uncertain support.
Public evidence does not provide complete annual income, participant counts or project budgets. The funding mechanisms should be described as experiments, not proven universal models. Voluntary contribution can support independent work and can be unpredictable.
The broader lesson is that efficiency in code does not eliminate labour. Protocol changes, security review, documentation and releases continue after the original performance problem is solved. A project that removes machine work may still depend on human work whose funding is invisible.
Kamp’s career does not fit a simple sequence of employment titles. His current public identity is that of an independent, self-employed systems programmer and writer. That independence can protect the ability to pursue work outside a corporate roadmap. It also exposes the financial fragility of maintaining infrastructure whose beneficiaries are dispersed.
The 2004 FreeBSD sponsorship experiment, Beer-Ware text and Varnish Moral License address different parts of this problem. Direct sponsorship asked a community to fund development time. Beer-Ware used a permissive social request rather than a payment obligation. The Moral License asks organisations receiving substantial value from Varnish to contribute voluntarily without changing their legal right to use the code.
None of these mechanisms supplies a complete project budget in the public record. Their importance lies in making an uncomfortable dependency visible. A permissive licence can remove legal friction and make adoption easy. It cannot guarantee that security triage, protocol work, documentation and release engineering will be financed.
Companies often solve the problem indirectly by employing maintainers, buying support or funding a foundation. Independent contributors may rely on consulting, sponsorship and voluntary payment. Each model shapes priorities. Customer funding can direct attention toward urgent deployments. Membership funding can favour large participants. Voluntary support can be broad and unreliable.
Kamp’s model asks beneficiaries to recognise value after receiving it. The approach preserves freedom and avoids converting upstream into a subscription product. It also depends on an ethical response that procurement systems are not designed to make. A company can comply perfectly with the licence and contribute nothing.
For leaders using Varnish or other open infrastructure, this is not a charitable side issue. Maintainer capacity affects vulnerability response, toolchain compatibility and protocol currency. A cost saved through open source can reappear as continuity risk when no one is paid to carry the difficult work.
“Bikeshedding” is a governance cost when decision rights are unclear
Kamp’s technical essays often move from code into project governance. The term bikeshedding describes the tendency for groups to spend disproportionate attention on easy, visible details while harder decisions receive less discussion. His July 2026 ACM Queue article continued this institutional reflection.
The phenomenon is more than annoying meeting behaviour. Infrastructure projects have limited reviewer attention. A long argument about naming can delay a security or architecture decision. Contributors participate where they feel confident, which can make trivial issues attract more voices than specialised ones.
Clear scope and decision rights can reduce the cost. A maintainer should explain which objections are material, when consensus is sufficient and when a decision must be made. Excessive central authority can silence useful review; an undefined process can make every change hostage to endless discussion.
Varnish’s deliberate narrowness is partly a governance tool. Refusing to become a general web server limits the number of features the project has to arbitrate. FreeBSD’s subsystem interfaces similarly localise decisions. Scope is not only architecture; it determines how many communities and incentives collide inside one repository.
Kamp’s argumentative style is first-person evidence of his views, not external proof that every project suffers the same failure. The writing is useful because it connects technical complexity with the social system that accepts and funds it.
A narrow core moves risk into its extension boundary
A narrow cache avoids becoming a complete application server and may require a TLS terminator, load balancer or another proxy for features outside its scope. Relying on kernel virtual memory simplifies object storage and makes kernel tuning important. Compiled VCL reduces request overhead and requires a secure build path. Every subtraction has an adjacent owner.
This is not a contradiction. It is the consequence of architecture. A system can be simpler by assigning responsibilities clearly rather than by making the total workload vanish. The operator must decide whether the chosen boundaries match team expertise and support arrangements.
Modern HTTP adds pressure. HTTP/2, HTTP/3, TLS, edge computing and complex routing may be handled by Varnish, adjacent projects or commercial products depending on version and architecture. The original design should not be judged as though every later feature was part of its founding scope.
Security and correctness can also resist minimalism. A cache policy needs enough information to protect personalised data. An observability system needs enough detail to diagnose failure. Removing a feature that owns a necessary control merely hides the dependency.
Kamp’s strongest lesson is not to minimise every program. It is to remove duplicated work and make the remaining owner explicit. When an adjacent system owns the function, the interface and failure path should be understood.
A focused cache cannot anticipate every authentication scheme, header transformation, routing decision or application-specific function. Varnish modules, commonly called VMODs, give operators and developers a way to extend VCL with additional functions without placing every feature in the core daemon.
The model supports Kamp’s preference for narrow infrastructure. The core can preserve a stable request engine and expose an extension interface. Specialised code can evolve with the organisation or vendor that needs it. A module can integrate data, cryptography or policy that would be inappropriate as a universal default.
Extensibility creates a software supply chain. A VMOD can run inside a sensitive process context, handle request data and influence cache or backend decisions. Its source, build system, release cadence and compatibility with the deployed Varnish version become part of the security boundary.
Binary or API compatibility matters during upgrades. A Varnish release can change interfaces that require a module rebuild or update. A commercial distribution may support a module not maintained upstream. An organisation that relies on one extension needs to know whether it can rebuild, replace and audit it independently.
Modules also affect incident attribution. A crash or incorrect response may originate in core code, VCL, a VMOD or the application behind the cache. Shared-memory logs and crash evidence should preserve enough context to separate those layers. Calling every failure “Varnish” hides the owner who can repair it.
The governance trade-off resembles FreeBSD’s subsystem model. A common interface allows specialised components to exist without centralising every decision. The interface still needs maintainers who can reject unsafe assumptions and communicate lifecycle changes.
For leaders, the extension inventory is as important as the Varnish version. A minimal core can produce a complex deployment when many modules, private VCL libraries and management wrappers accumulate around it. Kamp’s method remains valid only when the responsibility moved out of the core is named and supported elsewhere.
Varnish is defined by what the delivery stack owns around it
Varnish is often deployed between clients or an edge proxy and an application origin. That position can protect the origin from repeated work, reduce response latency and absorb traffic bursts when objects are reusable. It also places the cache inside a chain that may include DNS, TLS termination, load balancing, web application firewalls, content-management systems and managed delivery networks.
The product boundary is therefore easier to understand through exclusions. Varnish is not a complete content-delivery network. It does not own global points of presence, customer routing, certificate operations and a managed control plane merely because a CDN may use caching. It is not an application server. It does not decide the business meaning of a page. It is not automatically the best TLS endpoint or the only proxy in a modern architecture.
Those exclusions were part of the performance strategy. Every additional responsibility adds code paths, configuration, state and security review. A focused HTTP accelerator can optimise its object lifecycle and request path. An integrated edge platform can simplify procurement and operations by owning more of the chain. The choice depends on whether an organisation values component control more than a consolidated service boundary.
NGINX, Apache Traffic Server, Squid and HAProxy overlap with different parts of this space. NGINX combines web serving, proxying and caching. Traffic Server is a substantial caching proxy with its own architecture. Squid has a longer history across forward and reverse proxy use. HAProxy concentrates on load balancing and proxy functions rather than presenting the same cache model. Managed CDNs add global infrastructure and commercial operations.
A useful comparison does not ask which name is universally fastest. It asks which component owns cache semantics, TLS, routing, health, configuration, observability and support. Varnish’s design can be compelling when an operator wants explicit HTTP policy and can integrate the adjacent systems. A managed edge service may be more appropriate when the organisation does not want to own that integration.
This competitive context also changes the meaning of lock-in. An open-source cache reduces dependence on one hosted backend, but a deployment can become tied to custom VCL, VMODs, proprietary management layers or undocumented application behaviour. Portability exists in source and architecture; it still requires disciplined configuration and tests.
Varnish’s focused scope can make architectural replacement easier than replacing an integrated edge platform. The source, VCL and HTTP boundary are visible. That advantage disappears when an organisation relies on undocumented defaults, private modules or application assumptions that exist only in production.
A migration needs behavioural tests: which responses are cacheable, how variants are separated, when stale content is allowed, how invalidation works and what happens when the origin fails. Two proxies can accept similar configuration and differ at an HTTP edge case.
This is another form of state ownership. The executable configuration records part of the policy; tests record the intended outcome. Without both, an open component can become operationally locked in even though no licence prevents replacement.
Kamp’s minimalist architecture reduces the number of responsibilities to migrate. It does not eliminate the need to preserve the responsibilities that remain.
Failure tests reveal more than cache-hit benchmarks
Varnish became known through performance claims, yet the most revealing production tests are often the ones that reduce cacheability or damage an adjacent layer. A site can appear efficient while objects are hot and origins are healthy, then fail sharply during a purge, a miss surge or a slow backend.
A cache-miss storm changes the bottleneck. Requests that previously ended in the worker now wait for origin capacity. If many clients ask for the same uncached object, request coalescing or related policy can protect the backend, subject to version and configuration. If the application generates many variants, the cache can consume memory without achieving useful reuse.
Memory pressure is another test of the virtual-memory bargain. The kernel may reclaim pages, produce faults or compete with other processes. The cache can remain logically correct while latency becomes unstable. Operators need host-level memory and paging evidence alongside Varnish counters.
Configuration reload and restart tests expose operational ownership. Teams should know which objects survive, how clients are drained, how a failed VCL is rejected and how a worker crash appears in monitoring. Automatic restart is useful only when responders can distinguish a transient process failure from a repeated defect or exhausted resource.
Backend health policy needs failure injection as well. A check that removes capacity too aggressively can turn a partial problem into a full outage. Serving stale content can preserve availability and can violate a requirement for immediate freshness. The correct policy depends on the application, not on the cache alone.
These tests support Kamp’s broader systems argument. Performance is not a peak request rate. It is useful work delivered while state changes, resources become scarce and components fail. Removing duplicated machinery can improve that behaviour, provided the remaining boundaries are tested rather than assumed.
The enduring method is to put state where it can be owned
Across FreeBSD, Varnish and timekeeping, Kamp repeatedly asked where state belongs. Jails place isolation in the kernel. GEOM places storage composition in a shared framework. Timecounter abstracts hardware clocks. Varnish delegates residency to virtual memory and exposes HTTP policy through VCL. Shared logging separates event production from retention.
The designs differ and share a discipline: avoid two layers maintaining competing versions of the same truth. Duplicated state creates synchronisation work and unclear failure ownership. A common primitive can reduce both when it is strong enough for the workloads above it.
The method also explains Kamp’s interest in funding and governance. Code ownership is not enough if no one owns maintenance. A project scope is not clear if every feature discussion can expand it indefinitely. Technical subtraction requires institutional boundaries that preserve the decision after the original author leaves.
Varnish’s current community and FreeBSD’s continued evolution show that the work has moved beyond one engineer. That transition is part of the achievement. Kamp’s influence is best measured in the systems that others can maintain and in the questions his architecture forces operators to answer.
Performance is one outcome. The deeper outcome is legibility: fewer duplicated mechanisms, clearer control surfaces and a better chance of identifying which layer should be fixed when the system fails.
Member Briefing
Deeper Profile Context
Sign in with the right membership level to unlock the full briefing and source notes.
Only for Strategic Circle
Strategic Circle
Open to all readers. Unlock profile briefings after joining and signing in.
Join Strategic CircleOnly for Leadership Alliance
Leadership Alliance
For qualified IP-asset owners and management; sign in to unlock alliance briefings.
Join Leadership Alliance
