William Schor: From Unit Tests to Synthetic Canaries at Netflix

How generated workloads and production-like infrastructure help test a distributed key-value service.

WSWilliam SchorVortrag · Netflix
Kanal
GOTO Conferences
Veröffentlicht
26. Okt. 2026
Video
22:33
Lesezeit
3 Min.
Folien
4
Original
Englisch
Auf YouTube öffnen
Beim Scrollen schrumpft das Video in die rechte untere Ecke und läuft weiter. Untertitel folgen Ihrer Lesesprache.
LesespracheIn 2 Sprachen verfügbar
Diesen Artikel gibt es noch nicht auf Deutsch, daher wird das Original (Englisch) angezeigt.
ZUSAMMENFASSUNG

In 30 Sekunden

Netflix engineer William Schor explains the limits of hand-written examples, integration tests and conventional canaries, then describes synthetic canaries that generate gRPC traffic and compare service versions.

  1. 1Independent tests build confidenceImplementation and tests can share assumptions that production disproves.
  2. 2Generate input combinationsProperty-based testing can uncover cases missed by hand-picked examples.
  3. 3Integration still leaves gapsStorage and cache combinations can expose failures absent from isolated tests.
  4. 4Synthetic canariesA service specification and generated workload exercise realistic infrastructure.
  5. 5High load complicates diagnosisFinding a correctness violation at scale does not automatically make it reproducible.

Das Wichtigste

  1. Tests create confidence when they can challenge assumptions shared with the implementation.
  2. Property-based tests explore combinations, but integration and production fidelity still matter.
  3. Synthetic canaries generate workload sequences from service specifications and compare real infrastructure variants.
  4. Correctness failures under heavy load may be hard to reproduce and minimize.
VOLLTEXT

Den bearbeiteten Text nach Kapiteln lesen

Nur das Transkript
01

Confidence and testing

Schor explains why production experience and independent checks matter.

I work on Netflix’s key-value team, which owns Cassandra databases and layers that provide a key-value interface to the company. I want to trace how our testing evolved and how we tried to make those techniques useful to other online data-storage teams.

Tests clarify our thinking, express intent and preserve a contract, but I think their central purpose is confidence: enough confidence to change code and deploy it. Production experience can also give confidence because the code has survived actual runtime conditions.

A test and the implementation can share the same mistaken assumption. Code review, real dependencies and eventually production can disagree with a passing build. I want to bring some of the independence and fidelity of production experience earlier into the testing process.

02

From examples to properties

A missed scan combination motivates property-based testing.

Unit tests remain useful as contracts, communication and exercises in thinking through a design. But hand-picked cases can leave gaps. In our key-value store, scans of all records and all keys worked; scans of one record and one key worked too. Scanning all records for a particular key, however, triggered a failure that remained hidden for years.

Two passing scan tests
FOLIE 1 / 4Two passing scan testsThe existing examples cover only two combinations of record and key selection.

Property-based testing helps explore combinations without enumerating each example by hand. In the scan example, a two-by-two matrix of record selection and key selection makes the missing combinations visible. Generating cases across that space could have found the bug.

Generate the combinations
FOLIE 2 / 4Generate the combinationsA two-by-two matrix reveals cases missing from the hand-written tests.

We also compare different record-store implementations under generated inputs. An established implementation can act as an oracle for a new one, giving us more confidence as we add backends. This still assumes the implementations do not all share the same error.

03

Integration and fidelity gaps

External dependencies and configuration combinations expose further blind spots.

Property testing is not a silver bullet. In one case, an external producer generated filenames with a prefix while our code expected no prefix. Extensive internal tests shared the wrong assumption. Integrating the real producer’s code into a test hardened the contract between teams.

Integration tests still cover slices of a larger system. Different providers, caches and databases create a combinatorial space. One combination of store and cache violated read-your-writes consistency, but our tests had not exercised that combination. Adding a test only after each incident keeps us behind the expanding system.

A smoke test can start the whole service and exercise reads and writes, improving fidelity. Yet if workloads are still handwritten and fixed, it becomes a large unit test. The cost of creating each new workload discouraged complete coverage over time.

We considered copying production traffic to a candidate cluster. For stateful services, sending writes to real data can risk corruption. Sending them to a separate data source avoids that risk but creates a fidelity gap: a missing read might reflect a bug or simply data absent from the copy.

04

Synthetic canaries

Generated gRPC workloads exercise realistic infrastructure and compare versions.

Our goal became combining production-like infrastructure with the broad generated inputs of property testing. Synthetic canaries use a service specification, typically gRPC at Netflix, to drive a generic traffic generator. Each service supplies its specification and workload definitions rather than hand-coding every test.

The tooling provisions the infrastructure variants to test. A workload can specify the domain of fields, such as a range of IDs with a Zipfian distribution, as well as item counts and sizes. This gives us a way to model the shapes of traffic we expect rather than a single fixed example.

Generated workload variation
FOLIE 3 / 4Generated workload variationA specification defines ID distributions, counts and value sizes.

Requests can refer back to earlier steps. For example, after a put, a get can reuse the same ID and assert that the returned value matches. The library combines a gRPC specification with YAML generator descriptions, sends the resulting requests and checks relationships between them.

A read checks a write
FOLIE 4 / 4A read checks a writeA later get reuses the ID from a put and checks the returned value.

A canary can compare existing and candidate code, including performance. Integrated with resilience tooling, the approach can provision infrastructure and generate very large workloads, potentially millions of requests per second, approximating traffic shapes observed in production.

05

Limits and next steps

Large workloads reveal issues but can make failures difficult to reproduce.

There is an important limitation: when a correctness violation occurs amid millions of requests, reproducing the exact database state and sequence can be very difficult. Developers must reduce the failing case, and other tools may help. High-load testing can reveal a problem without making it easy to diagnose.

The broader vision is to combine generic traffic generation with infrastructure provisioning: run multiple versions or configurations of a service, exercise relevant traffic patterns across them, and check the results centrally. The online data-stores group has been pioneering this approach for wider use.

Mehr aus diesem Kanal

3 Folien39:12EN
GOTO Conferences· 28. Okt. 2026Cate Huston: How Rigour Supports AI-Assisted Development VelocityCate Huston · TwillA two-person team’s experience with release gates, automated checks, prioritization and the cost of shipping faster.KI-Engineering-FührungSoftware engineeringAI agents
5 Folien34:11EN
GOTO Conferences· 23. Okt. 2026Anatoliy Bilenko and Alberto Carretero: Making Database Protocols Reliable with Formal Methods and AIAnatoliy Bilenko, Alberto Carretero · CanonicalCanonical’s database engineers connect executable specifications, model-based tests, failure exploration, and reconstructed execution histories—and explain why none of these techniques proves a real system correct on its own.Entwicklungs-Workflows & TestsCode review & verificationObservability & Zuverlässigkeit+2
28:15EN
GOTO Conferences· 22. Okt. 2026Steve Poole on Open-Source Security and AI’s Maintenance ChallengeOlimpiu Pop, Steve PooleWhy faster vulnerability discovery increases pressure on maintainers, dependency users and upgrade processes.Software engineeringAI security
5 Folien46:36EN
GOTO Conferences· 21. Okt. 2026Don Syme: Building Agentic Automation Around Human CollaborationDon Syme · GitHubContinuous AI, repository workflows and the guardrails needed for unattended software maintenance.Agent orchestrationSoftware engineeringCoding-Agenten
28:23EN
GOTO Conferences· 19. Okt. 2026Learning Ash: Declarative Elixir Apps, Testing and ExtensibilityChristian Alexander, Rebecca Le, Zach DanielRebecca Le and Zach Daniel explain how their book and the framework evolved together.Software engineering
38:07EN
GOTO Conferences· 9. Okt. 2026Garrison Hinson-Hasty on Systems Programming with ZigTrevor Berrange Sanchez, Garrison Hinson-HastyA conversation about simplicity, memory, strings, graphics APIs and working with C.Programming LanguagesSoftware engineering