Copy the Interface, Not the Engine

On Monday the Supreme Court held that Google's copying of 11,500 lines of Java declaring code was fair use, ending eleven years of litigation. This is what that does and does not settle for anyone running a wire-compatible database or a drop-in fork, starting with the fact that the court decided fair use rather than whether an interface can be owned. The legal cloud lifted, and the layers where compatibility actually breaks are exactly where they were.

What the Court Actually Held

An API has two parts and only one of them is interesting here. There is the code that does the work: the sort, the hash lookup, the bytes moved onto a socket. Then there is the code that names the work, the method signatures and package structure and parameter lists that a programmer types in order to reach it. The opinion calls the second kind declaring code, and it is worth sitting with how strange a thing it is. It computes nothing. Delete the engine underneath and the declarations still compile and still do exactly as much as they did before, which is nothing.

Google copied roughly 11,500 lines of that declaring code out of the Java SE libraries so that people who already knew Java could write for Android without learning a new vocabulary. The opinion puts the figure in proportion: those lines are 0.4 percent of the 2.86 million lines in the API at issue, and the court treated that ratio as evidence that what was taken was the label rather than the thing. Google wrote its own implementing code. It took the names.

Oracle sued in 2010. Two juries, two trips to the Federal Circuit and one earlier denial of certiorari later, the case arrived at a court that had never squarely addressed how copyright applies to an interface, and on 5 April 2021 six justices held that Google's copying was fair use as a matter of law. Justice Breyer wrote it. Justice Thomas dissented, joined by Justice Alito. Justice Barrett, confirmed after argument, took no part.

I want to be precise about what that sentence contains, because the version circulating this week is not quite it. The court did not hold that APIs cannot be copyrighted. It explicitly declined to answer that, assumed for argument's sake that the declaring code could be copyrighted, and decided the case entirely on fair use. I am not a lawyer and this is not legal advice. But the difference between "you cannot own this" and "copying this was fair" is the difference between a rule and a judgment, and everything downstream inherits that distinction.

What It Left Standing

The copyrightability question is still open. The Federal Circuit's 2014 holding that the declaring code is copyrightable was not disturbed, because the court reached fair use without needing to reach it. Anyone telling you the Supreme Court declared interfaces free to copy is reporting the outcome and not the reasoning. The practical effect is close to the same for now. The doctrinal ground is not, and a future case with different facts starts from a different place than a rule would have given it.

Fair use is a judgment on facts, not a license. The court ran all four statutory factors and every one of them turned on specifics: that the declaring code sits at the functional edge of what copyright protects, that Android served a different market than Java SE, that the value of those lines came largely from what programmers had invested in learning them. Change the facts and you change the arithmetic. Nothing here is a blanket permission slip, and a company copying an interface to compete head-on in the same market has a materially worse set of facts.

The functional nature of code did real work. The most durable part of the opinion, to my eye, is the reasoning that computer programs always serve a functional purpose and that fair use therefore has an unusually large job to do in keeping the copyright monopoly inside its lawful bounds. That is a general statement about software rather than about Java, and it is the piece most likely to matter in cases that look nothing like this one.

The count was six to two, with a seat empty. Justice Barrett took no part, having joined the court after argument, so the majority is six of eight rather than six of nine. That is a normal thing and not a scandal. It is also a reminder that the margin here reflects a particular bench hearing a particular record, and the dissent, which would have found the copying not fair, is not a fringe position. Treating a six-two as settled law forever is how people get surprised.

The Ground Wire

Think about how much of what you run is a reimplementation of somebody else's interface. Samba speaks a protocol Microsoft designed. Wine implements the Windows API. MariaDB was built to drop into MySQL's socket without the application noticing. Half the object storage in the world answers to the S3 API because that is the API every client library already speaks, and a very large amount of database tooling talks the PostgreSQL wire protocol to things that are not PostgreSQL. In each case somebody copied the declaring surface and wrote a different engine.

The economics of that are not subtle. An interface with a decade of client libraries, tutorials, hiring pool and muscle memory behind it is worth more than the code beneath it, and the party that owns the interface knows it. If reimplementing the surface were reliably infringing, then the practical cost of adopting any widely used API would include a permanent option, held by its owner, to decide later that you may not leave. That is not a licensing term anyone negotiates. It is a fact about the shape of the industry.

The live example is three months old. In January, Elastic moved Elasticsearch and Kibana off the Apache 2.0 license, and AWS said on the twenty-first that it would fork the last Apache-licensed codebase, version 7.10, and maintain it. A fork like that keeps the interface deliberately - the indices, the query DSL, the client libraries - because keeping the interface is the only thing that makes it a migration path rather than a new product. Whatever it ends up being called, it is an argument for compatibility conducted entirely in the declaring surface.

So the ruling matters. I would just be careful about how much weight it carries in a design review, because the failure mode of a compatibility strategy has never really been legal. Google settled its own version of the technical problem years before the legal one: the Android class libraries moved to an OpenJDK basis around 2015, which resolved the engineering question of where the implementation came from while the courts spent another six years on the naming. The lawsuit was the risk. The compatibility was the work.

Compatibility Is a Spectrum

The declared surface is the easy part. Method names, endpoints, wire format, the shape of a request and a response. This is what a compatibility matrix in a datasheet is measuring, it is what an automated conformance suite can check, and it is genuinely most of the surface by count. It is also the layer where a competent team gets to ninety-five percent in a quarter, which is exactly why nobody's migration ever fails here and why the datasheet is not the document you want.

Error semantics are where the trouble starts. Real code branches on failure. It retries on one class of error, gives up on another, and treats a third as a data problem to be escalated. A reimplementation that returns a plausible but differently coded error for a full disk, a lock timeout or a rejected write has not broken your happy path. It has broken your retry loop, and it broke it in a way that only appears when the system is already degraded, which is the worst possible time to be discovering the difference.

Timing and consistency are the parts nobody wrote down. Whether a write is visible to the next read, whether a list operation reflects a delete that just returned success, whether an index is queryable the instant the insert acknowledges. AWS only made S3 strongly read-after-write consistent for all operations in December, and a decade of application code was written around the eventual behavior before that. Any store claiming to speak the same API has to pick a point on that spectrum, and the client cannot tell which one it picked until it is wrong.

The next layer is performance shape, not performance. Two engines behind one interface will have different query plans, different lock granularity, different points where a linear cost becomes quadratic. The interface promises the same answer and says nothing about the cost of getting it. A query that runs in milliseconds on the original because it hits an index the original happens to maintain will run correctly on the reimplementation and take four minutes, and the application will not report an error. It will just get slower until something upstream times out.

Then there is the undocumented behavior you already depend on. Every long-lived system leans on things the vendor never promised: the order a listing comes back in, a silent truncation, a field that happens to be populated, an operation that happens to be atomic. Nobody wrote these down because nobody knew they were load-bearing. They are discovered during the migration, one at a time, by the failure they cause, and the discovery rate is a function of how much traffic you have run through the new thing rather than how long you spent testing it.

Where Migrations Die

The pattern goes like this. The proof of concept goes beautifully, because a proof of concept exercises the declared surface and the declared surface is the part that works. A pilot workload moves and is fine for weeks. Then the first real incident arrives, and inside it the two systems disagree about something nobody had a name for, and the team is now debugging a semantic difference between two implementations of an interface while the pager is going. That is the moment the migration budget doubles, and it always arrives after the decision is irreversible in practice if not on paper.

The thing that would have caught it is not more testing. It is a different kind of testing, aimed at the layer where the differences live: run the failure paths deliberately, fill the disk, hold the lock, kill the connection mid-transaction, and compare what the two systems say rather than whether they both said something. Shadow real production traffic against both and diff the responses, including the errors, for longer than feels necessary. The point is not to find every difference. It is to move the discovery from the incident to the calendar.

I should concede the case where none of this bites, because it is common and I do not want to argue people out of a good move. If the interface you depend on is narrow, if your code uses a dozen operations rather than two hundred, and if you never depended on the parts that differ, then the reimplementation is genuinely a drop-in and the migration takes an afternoon. Plenty of them do. The trouble is that the property that decides it - how much undocumented behavior you lean on - is precisely the property nobody has an inventory of, so teams cannot tell in advance which case they are in.

And there is a second-order cost that outlives the migration. Once you are on a compatible implementation you are tracking two projects: the interface, which continues to evolve wherever it is defined, and your engine, which has to decide what to do about each change. Compatibility is not a state you reach. It is a subscription, renewed by whoever maintains the fork, and the question of who that is and what happens when they lose interest belongs in the evaluation next to the feature list rather than three years later.

I do not want to oversell Monday. This was a fair use holding on a specific record, not a rule that interfaces are free, and it went six to two on a bench of eight with a dissent that took the other view seriously. Someone will bring a case with worse facts and a different market and the analysis will come out somewhere else, and the people telling you today that the API question is closed are describing a mood rather than a doctrine. The cloud lifted. It did not resolve into a clear sky.

What stays with me is the asymmetry the case turns on. Eleven and a half thousand lines that compute nothing at all were worth eleven years of litigation, because they are the part everybody had already learned. The engine underneath was rewritten from scratch by a competitor and nobody had to be persuaded to accept the replacement, which tells you exactly where the value sat the whole time. Copy the interface and you inherit a decade of other people's habits. Copy the engine and you inherit a maintenance burden. It is the first one that people fight over, and it is the second one that has to actually work on the morning of the migration.