Eventual Consistency

3 posts

netflix3 min readCurated summary

High-Throughput Graph Abstraction at Netflix: Part I

Netflix’s Graph Abstraction is designed for OLTP graph workloads requiring millions of operations per second and millisecond-level latency, rather than open-ended analytical exploration. Built on existing Netflix abstractions, it supports real-time and optional historical graph views while handling nearly 10 million operations per second across 650 TB of data. Its core design emphasizes strong schemas, efficient traversal planning, low-latency caching, and controlled trade-offs such as eventual consistency and bounded query depth. ## OLTP Graph Use Cases - Netflix distinguishes between: - **OLAP workloads**, which prioritize large-scale exploration using RDF/SPARQL, property graphs, Gremlin, openCypher, or SQL. - **OLTP workloads**, which require extremely high throughput, low latency, and global availability. - OLTP queries may restrict traversal starting points, depth, or complexity to meet performance goals. - Key applications include: - **Real-Time Distributed Graph**, modeling dynamic relationships and interactions across Netflix. - **Social Graph**, supporting social connections in Netflix Gaming. - **Service Topology**, enabling real-time and historical analysis of internal services during incidents. ## Architecture and Netflix Data Abstractions - The Graph Abstraction builds on existing platform components rather than implementing storage and caching independently. - **Key-Value (KV) Abstraction** provides the latest state of nodes and edges and serves as the real-time index. - **TimeSeries (TS) Abstraction** can be added for historical graph views. - **EVCache** delivers low-millisecond latency, with additional specialized caching layers under experimentation. - The **Data Gateway Control Plane** manages: - Graph schemas - Dataset provisioning and deletion - KV and TS configuration ## Property Graph Model - Graphs contain typed nodes and edges, each with associated properties. - Properties are strongly typed to support: - Efficient filtering - Consistent data exports - Validation during writes - Edges may be: - **Unidirectional**, representing one-way relationships - **Bidirectional**, representing relationships traversable in both directions ## Namespaces and Provisioning - Data is isolated into logical units called **namespaces**. - Each namespace maps to a physical storage layer and may use dedicated or shared hardware. - Provisioning automation selects an appropriate hardware configuration based on: - Required throughput - Latency targets - Dataset size - Workload criticality ## Graph Schema and Query Optimization - Every namespace has an explicit schema defining: - Node and edge types - Valid properties and their types - Allowed relationships - Edge directions - Schemas are represented through edge mappings, such as an `account owns profile` relationship or a bidirectional `profile linked_to device` relationship. - Property definitions can specify types such as `TIMESTAMP` and `STRING`. - Servers load schemas into an in-memory metadata graph, enabling: - Rejection of invalid nodes, edges, and properties - Faster traversal-path planning - Deduplication of bidirectional edge traversals - Removal of impossible paths and incompatible filters - Servers periodically poll the Control Plane so schema changes are reflected without requiring manual updates. - Planned improvements include: - Using edge cardinality to reduce query fanout - Generating type-safe data-access layers - Making the Gremlin-like API schema-aware ## Real-Time Indexing with Key-Value Storage - KV stores the real-time representation of all graph nodes and edges. - Each namespace corresponds to a table, partitioned into records by unique IDs. - Records contain multiple sorted key-value items, effectively forming a map of sorted maps. - Writes to the same ID and key are idempotent, allowing safe retries and request hedging. - KV uses timestamp-based tokens to enforce **Last-Write-Wins (LWW)** semantics. - The post begins discussing the two-tier partitioning strategy for node storage, but the provided content ends before that design is explained. Netflix’s approach demonstrates that high-throughput graph serving depends on specialized constraints and platform integration rather than unrestricted graph querying. Strong schemas, bounded traversals, KV-based indexing, automated provisioning, and low-latency caching together provide a practical foundation for production-scale OLTP graph workloads.

Read original(opens in new tab)
lineOriginal article

Introducing a case of utilizing DDD in (opens in new tab)

LY Corporation’s ABC Studio developed a specialized retail Merchant system by leveraging Domain-Driven Design (DDD) to overcome the functional limitations of a legacy food-delivery infrastructure. The project demonstrates that the primary value of DDD lies not just in technical implementation, but in aligning organizational structures and team responsibilities with domain boundaries. By focusing on the roles and responsibilities of the system rather than just the code, the team created a scalable platform capable of supporting diverse consumer interfaces. ### Redefining the Retail Domain * The legacy system treated retail items like restaurant entries, creating friction for specialized retail services; the new system was built to be a standalone platform. * The team narrowed the domain focus to five core areas: Shop, Item, Category, Inventory, and Order. * Sales-specific logic, such as coupons and promotions, was delegated to external "Consumer Platforms," allowing the Merchant system to serve as a high-performance information provider. ### Clean Architecture and Modular Composition * The system utilizes Clean Architecture to ensure domain entities remain independent of external frameworks, which also provided a manageable learning curve for new team members. * Services are split into two distinct modules: "API" modules for receiving external requests and "Engine" modules for processing business logic. * Communication between these modules is handled asynchronously via gRPC and Apache Kafka, using the Decaton library to increase throughput while maintaining a low partition count. * The architecture prioritizes eventual consistency, allowing for high responsiveness and scalability across the platform. ### Global Collaboration and Conway’s Law * Development was split between teams in Korea (Core Domain) and Japan (System Integration and BFF), requiring a shared understanding of domain boundaries. * Architectural Decision Records (ADR) were implemented to document critical decisions and prevent "knowledge drift" during long-term collaboration. * The organizational structure was intentionally designed to mirror the system architecture, with specific teams (Core, Link, BFF, and Merchant Link) assigned to distinct domain layers. * This alignment, reflecting Conway’s Law, ensures that changes to external consumer platforms have minimal impact on the stable core domain logic. Successful DDD adoption requires moving beyond technical patterns like hexagonal architecture and focusing on establishing a shared understanding of roles across the organization. By structuring teams to match domain boundaries, companies can build resilient systems where the core business logic remains protected even as the external service ecosystem evolves.

figma3 min readCurated summary

Realtime Editing of Ordered Sequences | Figma Blog

Figma needed a way for multiple users to edit ordered object sequences simultaneously while ensuring every client eventually reached the same state. Although Operational Transformation (OT) could solve the problem, Figma chose fractional indexing because it is simpler, supports efficient reordering, and was sufficient for design documents. The trade-offs—such as possible interleaving and growing index lengths—were acceptable in Figma’s use case. ## The Realtime Ordering Problem - Figma documents contain ordered children inside groups, components, and other compound objects. - Users can insert, delete, or reorder objects while edits are applied locally and propagated asynchronously. - Because clients may receive operations in different orders, the system must guarantee eventual consistency: every client must end up with the same document. ## Operational Transformation - OT transforms concurrent operations so they preserve the intended result regardless of application order. - For example, an insertion before a deletion may require adjusting the deletion’s index so it still removes the intended characters. - OT offers: - Strong performance and low memory usage for very large sequences. - Linearized concurrent insertions rather than interleaved content. - However: - It is difficult to understand and implement correctly. - Reordering is typically represented as a delete followed by an insert. - Supporting more operation types increases implementation complexity substantially because operations must be transformed against one another. - Figma considered OT excessive because its sequences were not enormous, interleaving was acceptable, and reordering was especially common. ## Fractional Indexing - Each object receives a numeric position, and children are ordered by sorting these positions. - To insert between two objects, Figma assigns the new object the average of their positions. - Positions are arbitrary-precision fractions between 0 and 1, stored as strings to preserve precision. - Figma uses a compact base-95 representation, omitting the leading `0.` and using the full ASCII range. - Reordering requires changing only one position value. ## Trade-offs and Conflict Handling - Fractional indexes are easy to understand and implement, but: - Index strings can grow after many insertions. - Concurrent insertions may interleave. - Averaging fails if two neighboring objects have identical indexes. - Index growth is not a practical concern for Figma because document sizes and user-driven reorder operations are limited. - Interleaving is generally acceptable for design objects, which often do not overlap; users can manually correct unusual ordering. - If two clients insert between the same objects, the server assigns a unique position to prevent duplicate indexes. Figma’s experience suggests that a simpler, stable algorithm can be more valuable than a theoretically stronger one. Fractional indexing made collaborative ordering easier to maintain and extend while meeting the practical needs of a design tool.

Read original(opens in new tab)