Skip to content

Archive

Compatibility

9 articles
Software Engineering 15 Sep 2026 5 min read

Schema Renames Create a Compatibility Interval

Renaming a database column is a single catalog operation in many relational systems, but an application deployment can make that apparently atomic change span several software versions. If an old process still sends statements containing old_name after the database exposes only new_name, the schema is valid and the process is valid in isolation, yet their interface no longer matches. The central issue is not the rename operation itself. It is the interval in which multiple application versions can reach one database. During that interval, schema evolution behaves like an API compatibility problem.

Software Engineering 13 Sep 2026 7 min read

Schema Changes Are Multi-Version Protocols

A column rename looks atomic in a schema diff. A deployed system rarely experiences it that way. During a rolling release, old application processes can remain active after new processes start. Background jobs may run code built from another release. Replicas can lag behind a primary. Queued work can outlive the binary that created it. Data written before the change remains present after the new schema exists. The migration therefore crosses several versions of code and data at once.

Software Engineering 12 Sep 2026 7 min read

Expand and Contract at Database Schema Boundaries

A database column can be structurally valid and still be incompatible with the application processes using it. Renaming customer_name to display_name, for example, is trivial as a data-definition operation on many databases. The harder boundary appears when one application process still issues queries against the old name while another process already expects the new one. That overlap is common whenever application replacement is not atomic. Rolling deployments, multiple service instances, delayed workers, and independent consumers can leave more than one application version active at the same time. A schema migration then has two audiences: the database engine and every executable version that can reach the database during the transition.

Software Engineering 07 Sep 2026 9 min read

Evolving Data Shapes with Expand and Contract

A data change can look trivial in code and still be dangerous in a running system. Renaming a field, splitting one value into two, or changing a message shape may require several application versions, background jobs, and consumers to coexist while the change is in progress. The risky assumption is that the whole system changes at once. In practice, deployments take time, workers may finish old jobs after new code is live, and independently deployed consumers may upgrade later. If one release removes the old shape while something still depends on it, a locally correct change becomes a system failure.

Software Engineering 07 Sep 2026 9 min read

Designing Strict Input Contracts

Being tolerant of imperfect input can look helpful. A parser silently fixes an invalid value, an API treats an unknown option as a default, or a service accepts several spellings for the same field. The immediate caller succeeds instead of receiving an error. The cost often appears later. Once clients discover that invalid input is accepted, they may depend on that behavior. Tightening validation then becomes a compatibility change, and different implementations may interpret the same malformed input differently.

Software Engineering 07 Sep 2026 10 min read

Designing APIs for Observable Behavior

An API can keep every documented promise and still break its users. Suppose a function returns search results with no documented ordering guarantee. Its current implementation happens to return items alphabetically. A client notices that behavior and removes its own sorting step. Months later, the implementation changes and returns the same items in a different order. The API still satisfies its written contract, but the client breaks. This is the practical problem behind Hyrum’s Law: when an API has enough consumers, some consumers are likely to depend on almost any observable behavior, whether or not that behavior was intended as part of the contract.

Software Engineering 06 Sep 2026 9 min read

Designing Tolerant Readers for Evolving Contracts

A service reads a response from another system. It needs two fields, but its deserializer models twenty. A harmless producer change adds a field, changes an unused field, or expands an enum that the consumer never acts on. The consumer still breaks because it accidentally depended on more of the contract than its job required. A tolerant reader avoids that unnecessary coupling. It reads the smallest part of an external representation that the consumer needs and rejects changes only when they threaten assumptions the consumer actually relies on.

Software Engineering 04 Sep 2026 10 min read

Versioning Contracts, Not Just Releases

A version number is useful only when its consumers can make a decision from it. Suppose a library changes from 2.4.1 to 2.5.0. A developer considering the upgrade wants to know something practical: can existing code keep working, or must it change? The answer does not come from how much code the maintainer edited. It comes from whether the release changed a contract that consumers depend on. That contract includes more than function names. It can include accepted inputs, returned values, error behavior, configuration, file formats, command-line options, extension points, and other observable behavior that the project promises to preserve.

Software Engineering 01 Sep 2026 5 min read

Evolving APIs Without Breaking Clients

An API is not only an HTTP path or function signature. It is a contract about syntax, semantics, timing, errors, ordering, defaults, and lifecycle. Breaking changes often happen because a server remains syntactically compatible while changing one of those less-visible assumptions. Safe API evolution starts by identifying what clients can reasonably depend on and designing changes that allow old and new versions to coexist. Compatibility has multiple dimensions A change can preserve JSON shape and still break clients.