I. The Spreadsheet That Prices the Wrong Side
The spreadsheet usually looks responsible. It has columns for license cost, feature coverage, implementation effort, support tier, security certification, data residency, integration work, and time to production. A few vendors are compared side by side. Scores are weighted. The preferred option emerges with the calm appearance of arithmetic. Someone adds a risk note. Someone else asks whether legal has reviewed the contract. The team moves forward.
The spreadsheet is not useless. It is doing a real job. It prices the cost of adoption. It helps a team avoid an obviously wrong purchase. It forces a conversation that would otherwise remain anecdotal. In many organizations, that alone is progress.
But the spreadsheet is also pricing the wrong side of the decision.
The cost that matters most in a long-lived system is often not the cost of entering a vendor relationship. It is the cost of leaving it. That cost is rarely visible at the moment of selection because the system has not yet grown around the dependency. There is no data volume yet. No operational runbook. No monitoring estate. No accumulated team habit. No reporting layer. No regulatory process depending on an export format. No board-level renewal deadline. The dependency is still small enough to look like a tool.
Five years later, the same dependency has become part of the organization’s operating surface. The data model has absorbed its assumptions. The deployment process has normalized its constraints. The team has learned its vocabulary. Adjacent systems depend on its behavior. Renewal is no longer a procurement event; it is a production risk event. At that point the vendor’s price, license, roadmap, acquisition status, or support posture can change the architecture without touching a line of code.
That is the moment most vendor-selection processes fail to price. They compare what it costs to start, then call the result total cost of ownership. The name is too confident. A cost model that excludes departure is not total. It is an adoption model with a longer invoice horizon.
The missing metric is exit cost: the engineering, operational, contractual, data, skill, and opportunity cost of replacing a dependency under realistic conditions. Exit cost does not mean every dependency must be easy to replace. Serious systems make commitments. Databases are commitments. Cloud platforms are commitments. Workflow engines, identity providers, observability stacks, ERP systems, market-data feeds, and trading venues are commitments. Architecture is not the avoidance of commitment; it is the discipline of knowing which commitments have been made, what makes them expensive, and what options remain when the assumptions behind them stop holding.
There is a useful harshness in this framing. It removes the comfort of vendor-neutral language. A dependency is not “strategic” because it appears in a roadmap deck. It is strategic when leaving it would change the organization’s delivery calendar, operating model, regulatory posture, or negotiating position. That kind of dependency deserves a better review than a feature matrix and a discounted three-year quote. It deserves the same seriousness the organization gives to data loss, security exposure, and production availability, because it can become all three at once when the relationship changes under load.
The argument of this essay is simple: every serious vendor selection should carry an explicit exit-cost score. Not as a theatrical worst-case scenario. Not as a ritual line in a risk register. As an architecture metric beside performance, security, operability, and cost. A team that cannot describe how it would leave a vendor has not selected a vendor. It has deferred an architecture decision until the day the decision is most expensive to make.
II. What Exit Cost Contains
Exit cost is often reduced to migration effort: how many engineers, how many months, how many scripts. That is the easiest portion to see and the least complete. A dependency creates departure cost across several layers. Each layer has a different owner, appears on a different timeline, and becomes visible to a different part of the organization.
The first layer is data extraction cost. This is the cost of getting the organization’s own data out of the system in a complete, consistent, usable form. It includes export bandwidth, export fees, snapshot mechanics, API throttling, historical retention gaps, deleted-record semantics, identity mapping, audit trails, attachments, binary payloads, and everything else that turns “download the data” into a project. Extraction cost is the deepest layer because data outlives implementations. A service can be rewritten. A queue can be drained. A deployment system can be replaced. Ten years of customer events, market ticks, invoices, medical records, experimental results, or operational telemetry cannot be recreated because an export path was not tested.
The second layer is semantic translation cost. Data that can be exported is not necessarily data that can be used. Vendor systems embed assumptions in field names, state machines, null behavior, time-zone handling, permission models, object lifecycles, reconciliation rules, and consistency guarantees. A CRM “account,” a cloud “project,” a warehouse “dataset,” a trading “position,” and a Kubernetes “service account” are not neutral nouns. They are domain objects inside a particular operating model. Translation cost is the work of turning one vendor’s ontology back into the organization’s own domain language, then forward into a replacement system without losing business meaning.
The third layer is runtime substitution cost. This is the cost of replacing the behavior that production systems call every day. APIs, SDKs, query dialects, authorization flows, message formats, retry semantics, service-level assumptions, latency envelopes, and failure modes all sit here. Surface adapters help, but they only protect the parts of the surface that were deliberately isolated before the migration pressure arrived. A team that imported vendor concepts directly into its domain model has already spent the abstraction budget. The migration will not be an adapter swap. It will be a domain rewrite wearing a migration label.
The fourth layer is operational reconstitution cost. Systems are not only code and data. They are runbooks, dashboards, alerts, backup policies, on-call habits, incident classifications, access reviews, deployment processes, capacity models, compliance evidence, and support escalations. A managed service that looks cheap on an invoice may carry a large hidden operational balance because the organization has learned to operate through the vendor’s console, metrics, permissions, support language, and failure vocabulary. Leaving means rebuilding those habits elsewhere while production is still running.
The fifth layer is skill replacement cost. Every dependency creates a curriculum. Engineers learn the vendor’s sharp edges. Operations teams learn the maintenance windows. Security teams learn the permission model. Finance teams learn the billing codes. Architects learn the undocumented constraints. Some of that knowledge transfers to the replacement. Some does not. The non-transferable portion is a real asset whose value decays at migration time. Skill replacement cost is not an argument against specialization; it is an argument for knowing whether the specialization is in the underlying discipline or in a vendor-shaped interface to that discipline.
The sixth layer is contractual timing cost. A technically simple exit can become expensive when the contract controls the clock. Renewal deadlines, termination notice periods, minimum commits, reserved capacity, support cutoffs, price-protection windows, audit clauses, and bundling conditions can force the organization to move faster than its engineers should move or stay longer than its economics justify. Contractual timing cost is where procurement and architecture meet. If procurement negotiates the entry without understanding the exit, it can accidentally move technical risk into a legal calendar.
The seventh layer is opportunity cost. A migration consumes the same people who would otherwise improve the product, harden the platform, reduce latency, automate operations, clean the data model, or build the next revenue-bearing capability. This cost rarely appears in vendor comparison because it is not an invoice. It is still paid. A six-month migration is not only six months of migration spend. It is six months of architectural attention unavailable for anything else.
There is an eighth layer that cuts across the others: coordination cost. Vendor exits rarely remain inside one team. Data engineering, security, finance, legal, procurement, product, operations, and customer support all discover a stake in the dependency at different moments. The migration plan that looked like a technical project becomes an organizational synchronization problem. This is why mature exits feel slower than the code diff suggests. The replacement might be technically straightforward while the surrounding organization needs months to align permissions, contracts, customer notices, audit evidence, reporting definitions, and support procedures. Coordination cost is the tax paid for discovering too late that the vendor was not a component but a shared operating assumption.
These layers compound. A system with clean exports but deep semantic coupling still has high exit cost. A system with portable APIs but no operational replacement still has high exit cost. A system with a cheap migration but a renewal deadline three months away still has high exit cost. Exit cost is a system property, not a checklist item. It emerges from the whole arrangement.
This is why a single migration estimate is usually misleading. “Three engineers for three months” may describe the code path. It says nothing about the data freeze window, the reconciliation process, the security re-certification, the customer-contract implications, the reporting restatement, or the delay to other platform work. A useful exit-cost estimate names the layers separately. If a layer is unknown, it stays unknown in the estimate. Unknown is not a detail to smooth over; it is the signal that the architecture review has found work.
III. Why Total Cost of Ownership Is Not Enough
The standard business language for this problem is total cost of ownership. TCO is useful, but it is not sufficient. It tends to ask what the selected option will cost if the relationship continues. Exit cost asks what the selected option will cost if the relationship must change.
That difference matters because vendor decisions are made under uncertainty. The vendor may change its license. The company may be acquired. The product may be bundled into a larger platform. Support may be narrowed. The roadmap may move away from the workload. A regulator may change the rules. The organization’s data volume may grow faster than expected. A system that was correct for one business phase may become wrong for the next. None of these outcomes requires the original vendor decision to have been foolish. It only requires time to pass.
TCO usually treats the vendor as stable. Exit cost treats the relationship as a changing boundary. That is the architectural frame.
Donella Meadows’s systems-thinking work is useful here because it separates component quality from system behavior. A system’s behavior is determined by its structure: feedback loops, delays, stocks, flows, rules, and goals, not by the local quality of each part in isolation [1]. A vendor can be excellent and still produce a fragile architecture if the surrounding system has no affordable path away from it. Conversely, a less feature-rich dependency can be architecturally stronger if its data model is portable, its interfaces are standard, its license is stable, and the team can operate it independently.
This is why “best tool for the job” needs a second clause. The better question is: best tool for the job, weighted by exit cost, under the assumption that the relationship may change before the system dies.
The word optionality is more precise than flexibility here. Flexibility often means the system can do many things. Optionality means the organization has preserved the right to make a different decision later without paying a punitive price. Optionality has value even if the option is never exercised. A team may stay on a vendor for a decade. If the exit path is known, tested, and bounded, the vendor relationship remains a choice. If the exit path is unknown, untested, and unbounded, the vendor relationship becomes a constraint that masquerades as a choice.
The mistake is treating exit cost as pessimism. It is not pessimism. It is the same discipline as backup testing. A team does not test restore procedures because it expects the disk to fail tomorrow. It tests restore procedures because a backup that has never been restored is an opinion, not a capability. A vendor exit path that has never been modeled is the same kind of opinion.
The practical consequence is uncomfortable: a vendor-selection process that cannot produce an exit-cost estimate is incomplete even if it has produced a beautiful TCO model. The TCO model tells the organization what it expects to pay if the relationship behaves. The exit-cost model tells the organization what it may pay if the relationship becomes a problem. Both numbers matter. Only one usually gets written down.
The portfolio effect makes the omission worse. One high-exit dependency can be acceptable. Ten high-exit dependencies whose exits all depend on the same cloud account, identity provider, data warehouse, or enterprise contract are not ten separate risks. They are correlated risks. A pricing change, acquisition, compliance finding, or support-policy change can hit several of them at once. This is the same systems error that appears in financial portfolios: local diversification that masks shared exposure. Vendor-selection spreadsheets usually score products one at a time. Architecture has to score the shape they create together.
The portfolio view also explains why small decisions deserve attention. A team does not wake up one morning and decide to make departure impossible. It accepts one proprietary metric format because the dashboard is better. It accepts one vendor SDK because the auth flow is smoother. It accepts one managed feature because it avoids a quarter of engineering work. Each decision is locally reasonable. The aggregate is a system whose future movement is constrained by a thousand reasonable choices. Exit cost is the metric that makes the aggregate visible while the choices are still small.
IV. Exit Cost Becoming Visible
Exit cost is easiest to dismiss before it materializes. The recent record has been useful because it has made several forms of exit cost visible in public.
The first example is cloud data transfer. For years, outbound data transfer charges were treated as a normal part of cloud pricing. They were discussed as billing mechanics, not architecture. That framing changed when regulators and providers began treating cloud switching as a market-structure issue. The EU Data Act, Regulation (EU) 2023/2854, explicitly seeks to facilitate switching between data-processing services and improve interoperability [2]. Google Cloud’s January 2024 announcement removed network data transfer fees for customers who want to stop using Google Cloud and migrate their data elsewhere, and framed the change as making cloud switching easier [3].
The important detail is not that one provider changed one price. The important detail is that the industry had to acknowledge data movement as a switching barrier. That is exit cost in its most literal form: the cost of moving the organization’s own data out of the place where it currently lives. The fee is only the visible part. The deeper cost is data gravity: the analytics jobs, dashboards, training pipelines, backups, access policies, and downstream services that accumulate around the data while it sits there.
For architecture review, the lesson is sharper than “avoid egress fees.” Fees can be negotiated, waived, or absorbed. Coupling to data location is harder. A team that stores raw events, curated tables, model features, audit logs, and backups in one platform has not merely chosen storage. It has chosen where future compute wants to live. The longer that choice runs, the more expensive it becomes to move the data and the workloads separately. The exit-cost question therefore belongs at the start of the data-platform conversation: which data must remain portable, at what granularity, in what format, under what throughput, and with what proof that the export actually works?
Architectural lesson: data egress is not a billing footnote. It is an architectural property of every workload whose data volume grows over time.
The second example is Terraform. In August 2023, HashiCorp announced that future releases of its products would move from the Mozilla Public License to the Business Source License [4]. The company’s stated goal was to preserve investment in its products while limiting competitive commercial use. End users could continue many forms of usage, but the change still altered the governance and risk profile of a tool that had become foundational infrastructure for many organizations. The response was immediate: OpenTofu was created as a Terraform fork in response to the license switch, with its FAQ describing the new license and use grant as ambiguous for companies, vendors, and developers trying to understand future boundaries [5].
Terraform’s exit cost was not only source code. It was state files, modules, provider ecosystems, CI/CD pipelines, internal platform wrappers, drift-detection processes, policy checks, and the mental model of infrastructure-as-code teams. Organizations with disciplined module boundaries, isolated backend state, and limited vendor-specific extensions had a narrower path to OpenTofu or another tool. Organizations that had embedded Terraform deeply into internal workflow engines, custom providers, and governance automation faced a broader migration surface.
This is the important property of infrastructure tooling: it becomes the grammar through which the organization describes reality. A change in that grammar is not like changing a formatter or a test runner. It touches provisioning, compliance, disaster recovery, access control, and auditability. The most expensive part of leaving may not be the command-line tool. It may be the confidence that the replacement describes the same infrastructure with the same safety properties. State compatibility matters because state is memory. Provider compatibility matters because providers are the boundary to real systems. Registry continuity matters because modules are organizational reuse encoded as dependency metadata.
Architectural lesson: a tool that describes infrastructure becomes infrastructure. Its governance model belongs in the architecture review, not only in the legal review.
The third example is Redis. In March 2024, Redis announced that future Redis releases would no longer be distributed under the BSD 3-Clause license and would instead use RSALv2 and SSPLv1 source-available licenses [6]. Within days, the Linux Foundation announced Valkey, an open-source alternative intended to continue development from Redis 7.2.4 under the BSD 3-Clause license [7]. The fork reduced exit cost for some users because the wire protocol, data model, operational expectations, and contributor base had a high degree of continuity. It did not eliminate exit cost. Managed services had to decide what to support. Operators had to evaluate compatibility. Security teams had to understand the new project’s governance. Engineers had to decide whether the fork, the original vendor distribution, or a different cache entirely best fit the workload.
The Redis case is a useful corrective to simplistic open-source comfort. A permissive license lowered the cost of creating a fork when the license changed. It did not make every downstream migration free. The ability to fork is not the same as an already-tested exit path. It is a ceiling on unilateral vendor power, not a substitute for operational preparation.
Compatibility also has depth. A cache replacement can be protocol-compatible and still differ in cluster behavior, persistence edge cases, memory fragmentation, module support, observability, managed-service availability, operational tooling, and failure recovery. Most applications use only a subset of a data store’s behavior until they do not. The rare command, the old client library, the unusual persistence setting, or the implicit latency expectation becomes the migration issue. This is why exit-cost review has to ask not only whether an alternative exists, but which parts of the current behavior the organization actually depends on.
Architectural lesson: open governance and compatible forks can cap exit cost, but only if the consuming architecture has avoided unnecessary semantic and operational coupling.
These cases share a pattern. The original decisions looked local: cloud storage, infrastructure-as-code tooling, caching infrastructure. The later cost was global: data movement, governance uncertainty, service replacement, operational retesting, skill transfer, roadmap risk. Exit cost was present from the first day. It only became visible after the surrounding systems had made it expensive.
V. The Counter-Position: Not Every Exit Must Be Cheap
The exit-cost frame can be abused. The weak version turns every vendor discussion into a suspicion exercise and every proprietary feature into a moral failure. That is not architecture. It is ideology with a spreadsheet.
Some dependencies should be hard to leave because they are central to the business. A payment processor, a core banking platform, a manufacturing control system, a regulated clinical data system, a market-data feed, or a specialized hardware vendor may carry unavoidable coupling. The correct question is not whether exit cost exists. It always exists. The question is whether the organization understands it and whether the expected value of the dependency justifies it.
There are also cases where paying a vendor is the rational way to buy time. A small team without database operations expertise may be correct to use a managed database. A startup may be correct to accept cloud-platform coupling while searching for product-market fit. A regulated enterprise may be correct to use a vendor whose compliance package is stronger than anything the internal team could assemble in the required timeframe. A quant team may be correct to buy clean market data rather than spend years building exchange-by-exchange ingestion and normalization. The fact that exit cost exists does not make these decisions wrong.
The discipline is to avoid pretending the trade does not exist. Managed services are often a purchase of operational compression: less internal work now, more vendor dependence later. Proprietary platforms are often a purchase of feature compression: more capability now, less control over the future shape of that capability. Bundled suites are often a purchase of integration compression: fewer seams now, larger replacement units later. These can be excellent trades. They are still trades.
False precision is another danger. Exit cost cannot be known exactly. A five-year migration estimate made during vendor selection will be wrong. The team does not yet know the future data volume, future organization shape, future compliance surface, or future product direction. But uncertainty is not a reason to omit the metric. Security risk is uncertain. Capacity growth is uncertain. Revenue forecasts are uncertain. Architecture deals in uncertain estimates constantly. The point is not to compute the perfect number. The point is to force the missing conversation while options still exist.
The strongest counter-position is that most exits never happen. That is true in many systems. But it misses the economic structure of optionality. Insurance is not worthless because most buildings do not burn down. Backup restore tests are not worthless because most disks do not fail this week. A tested exit path has value even when unused because it changes the power balance of the relationship. A team that can leave negotiates differently from a team that cannot. A vendor knows the difference as well.
So the rule is not “choose the lowest exit cost.” The rule is “know the exit cost before choosing the dependency.” Sometimes the right decision is to accept high exit cost deliberately. What should not survive review is accidental high exit cost discovered only after the system depends on it.
There is a leadership consequence here. High exit cost is not automatically an engineering objection. It is a governance fact. A business may decide that speed, certification, support guarantees, market access, or feature depth justify the dependence. That decision should be visible at the right level. If a team accepts high exit cost to meet a deadline, leadership should know what has been borrowed from the future. If leadership accepts high exit cost for strategic reasons, engineering should know that the commitment is deliberate. What causes damage is the silent middle: engineers assuming procurement understood the technical exposure, procurement assuming engineering can migrate if needed, and leadership assuming both groups have priced the trade.
VI. The Discipline of Pricing Departure
Exit cost becomes useful only when it changes practice. It needs to be concrete enough to affect decisions and light enough to survive real delivery pressure. Seven practices do most of the work.
Make exit cost a scored line item in vendor selection. The score does not need theatrical precision. Use a simple scale: low, bounded, high, unknown. Low means the dependency can be replaced with limited code and operational change. Bounded means the migration is real but understood. High means the dependency has deep data, operational, semantic, or contractual coupling. Unknown means the team has not done enough work to know. Unknown should be treated as high until proven otherwise.
Separate adoption cost from departure cost. A vendor can be cheap to adopt and expensive to leave. Another can be expensive to adopt and easier to leave. These are different numbers and should not be blended into one comforting total. Adoption cost belongs to delivery planning. Departure cost belongs to architecture risk. When they conflict, the decision needs explicit ownership.
Test the data exit before production scale arrives. Export a representative dataset. Restore it into a neutral format. Reconcile counts, identities, timestamps, deletes, permissions, and audit records. Measure throughput and throttling. Document what does not come out cleanly. This test should happen before the data volume is large enough to turn an unpleasant discovery into a strategic problem.
Keep the domain model outside the vendor model. Application code can call vendor APIs. The domain language should not become vendor language unless the business domain truly is the vendor’s domain. Internal objects should describe the organization’s reality: customer, instrument, position, invoice, entitlement, observation, experiment, device, event. Vendor-specific concepts should be translated at boundaries. This is the abstraction that matters; wrapper classes around SDK calls are secondary.
Preserve neutral operational evidence. Backups, logs, metrics, traces, access reviews, incident records, schema migrations, and deployment history should not exist only inside the vendor’s control plane. If the organization cannot produce operational evidence without the vendor console, it has coupled auditability to the vendor. That coupling becomes visible during incidents, audits, renewals, and exits.
Read contracts as architecture documents. Minimum commits, renewal windows, termination assistance, export rights, support sunset clauses, audit rights, price-indexing terms, and product-bundling language all shape the system’s future movement. The architecture review should feed procurement with technical consequences before signature, not after renewal pressure appears.
Re-score exit cost when the workload changes. A low-exit dependency can become high-exit when data volume grows, when a prototype becomes a regulated system, when a regional deployment becomes global, when a side integration becomes a core workflow, or when a vendor feature becomes embedded in customer-facing behavior. Exit cost is not a one-time score. It is a property that drifts.
Keep an exit rehearsal small enough to run. The full migration may be too expensive to rehearse, but one slice should be real. Export one tenant. Rebuild one dashboard. Move one service to the alternative API. Restore one backup outside the vendor. Run one reporting cycle from neutral data. Small rehearsals expose false assumptions early: missing fields, undocumented throttles, brittle scripts, permission gaps, time-zone errors, broken lineage, and operational steps that exist only in someone’s memory. A rehearsal is not a plan. It is evidence that the plan has touched reality.
The practical artifact is small: an exit-cost note attached to each critical dependency. It should answer five questions. What data must leave? What code must change? What operational processes must be rebuilt? What contractual clock controls the exit? What business capability is paused while the exit runs? If the team cannot answer, that is the finding.
The note should be owned by architecture but readable by procurement and leadership. If it reads like an internal implementation memo, it will not shape the contract. If it reads like procurement boilerplate, it will not shape the system. The useful form is blunt: dependency, reason for use, exit-cost score, highest-cost layer, known alternatives, proof of data export, contractual constraints, review date. One page is enough. A one-page note that exists beats a perfect risk model nobody maintains.
The compact working version is the Vendor Exit-Cost Checklist. It is deliberately short enough to use during a real review rather than after it.
This note changes the tone of vendor selection. It moves the conversation from preference to consequence. It makes procurement aware of engineering reality. It makes engineering aware of contractual reality. It gives leadership a clearer view of whether the organization is buying capability, renting capability, or surrendering optionality for speed.
VII. The Decision After the Decision
Vendor selection is usually treated as a decision that ends when the contract is signed and the implementation begins. In architecture, that is backwards. The contract is the beginning of the decision’s life, not the end. The real decision is made again every month as data accumulates, runbooks harden, integrations multiply, and people learn the vendor-shaped way of operating.
That is why exit cost belongs in the first review. The cost of leaving is lowest when the system is young enough to ignore it. By the time the cost is obvious, the organization has already built the thing that makes it obvious.
This does not mean avoiding vendors. It means refusing to confuse a vendor relationship with a law of nature. A platform may be the right platform. A managed service may be the right service. A proprietary feature may be worth the commitment. But the commitment should be named. Its exit should be priced. Its assumptions should be revisited when the system changes.
The earlier essay on vendor lock-in described the slow failure mode: proprietary dependencies accumulating until optionality is gone. The cloud lock-in essay described the same pattern at platform scale. The cloud repatriation essay applies that reasoning to workload placement: not whether cloud is good or bad, but where a specific workload belongs once its demand, data, coupling, and operating model are visible. Exit cost is the operational metric that turns those arguments into a review practice. It gives the team a way to ask the uncomfortable question before the uncomfortable moment arrives.
The question is not whether the system can avoid dependency. It cannot. The question is whether the organization still owns the decision after the dependency becomes successful.
References
[1] Meadows, D. H. (2008). Thinking in Systems: A Primer. Chelsea Green Publishing. ISBN: 978-1-60358-055-7. https://www.chelseagreen.com/product/thinking-in-systems/
[2] European Union. Regulation (EU) 2023/2854 of the European Parliament and of the Council of 13 December 2023 on harmonised rules on fair access to and use of data (Data Act). https://data.europa.eu/eli/reg/2023/2854/oj
[3] Google Cloud. "Cloud switching just got easier: Removing data transfer fees when moving off Google Cloud." January 12, 2024. https://cloud.google.com/blog/products/networking/eliminating-data-transfer-fees-when-migrating-off-google-cloud
[4] HashiCorp. "HashiCorp adopts Business Source License." August 10, 2023. https://www.hashicorp.com/en/blog/hashicorp-adopts-business-source-license
[5] OpenTofu. "Frequently Asked Questions." https://opentofu.org/faq/
[6] Redis. "Redis Adopts Dual Source-Available Licensing." March 20, 2024. https://redis.io/blog/redis-adopts-dual-source-available-licensing/
[7] The Linux Foundation. "Linux Foundation Launches Open Source Valkey Community." March 28, 2024. https://www.linuxfoundation.org/press/linux-foundation-launches-open-source-valkey-community