今日已更新 80 条资讯 | 累计 20052 条内容
关于我们

标签:#systemd

找到 70 篇相关文章

AI 资讯

HLD Fundamentals #4: How Systems Scale: From 0 to 100 Million Users

One of the most common system design interview questions is: "How would you scale a web application from 100 users to 100 million users?" The answer is rarely a single technology. Instead, systems evolve through multiple stages, with each stage solving a specific bottleneck. This article walks through the typical evolution of a scalable system and explains why , how , and when each component is introduced. 1. Single Server Why Start Here? Every application starts simple. In the beginning: Traffic is low Development speed matters more than scalability Infrastructure costs should be minimal What Is It? A single machine handles everything: Frontend Backend Database Users | v Single Server ├── Application └── Database How Does It Work? User sends request. Application processes request. Database stores and retrieves data. Response is returned. Everything happens on one machine. Problem As traffic grows: CPU becomes overloaded Memory becomes insufficient Database competes with application for resources A single server becomes a bottleneck. Interview One-Liner A single server architecture is simple and cost-effective but becomes a bottleneck as traffic and resource usage increase. 2. Application and Database Separation Why Do We Need It? The application and database have different workloads. Application Server: Uses CPU Handles business logic Database Server: Uses memory and storage Handles queries Keeping them together causes resource contention. How Does It Work? Move the database to a separate machine. Users | v Application Server | v Database Server Benefits Independent scaling Better resource utilization Improved performance Example Suppose an e-commerce website receives thousands of requests. The application handles: Authentication Order processing API responses The database handles: Product data Orders User information Separating them prevents one workload from affecting the other. Interview One-Liner Separating the application and database allows each layer to scal

2026-06-18 原文 →
AI 资讯

HLD Fundamentals #3: Microservices Design Patterns: Strangler, Saga, and CQRS

When organizations scale, a simple monolithic architecture often becomes difficult to maintain, deploy, and scale. This is where microservices come into the picture. However, moving to microservices introduces new challenges: How do we migrate from a monolith safely? How do we handle transactions across multiple services? How do we scale read-heavy applications efficiently? Three popular patterns solve these problems: Strangler Pattern – Monolith to Microservices Migration Saga Pattern – Distributed Transaction Management CQRS (Command Query Responsibility Segregation) – Read/Write Scalability 1. Strangler Pattern Why Do We Need It? Most companies cannot shut down a production monolith and rewrite everything from scratch. A complete rewrite is risky because: Development takes a long time. Existing customers are affected. Bugs can impact business operations. Rollback becomes difficult. The Strangler Pattern allows teams to migrate gradually with minimal risk. What Is It? The Strangler Pattern is a migration strategy where new microservices slowly replace parts of a monolithic application until the monolith is no longer needed. The name comes from the strangler fig tree, which gradually grows around another tree and eventually replaces it. How Does It Work? [Insert diagram here showing Client → API Gateway → Monolith + Microservices] Step 1 All requests go to the monolith. Client | v Monolith Step 2 Introduce an API Gateway (or Controller). Client | v API Gateway | v Monolith Step 3 Extract one module into a microservice. Client | v API Gateway |------> Order Service | v Monolith Step 4 Gradually move more modules. Client | v API Gateway |------> Order Service |------> Payment Service |------> Inventory Service | v Monolith Step 5 Eventually remove the monolith completely. Example Consider an e-commerce application. Initially, everything exists inside one application: Monolith ├── Orders ├── Payments ├── Inventory └── Users Over time: Orders become Order Service Payme

2026-06-18 原文 →
AI 资讯

[System Design] Part 4 — Amazon CONDOR & Anticipatory Shipping

Amazon Fulfillment: The Three Tiers of Optimization Amazon processes billions of orders annually through a network of over 175 fulfillment centers globally. To maintain their 1-2 day (or same-day) delivery guarantees, they built a 3-tier optimization architecture: ┌─────────────────────────────────────────────────────────────┐ │ TIER 1: ANTICIPATORY SHIPPING (Long-term — weeks/months) │ │ → ML predicts demand → Moves inventory close to customers │ │ BEFORE they place an order │ ├─────────────────────────────────────────────────────────────┤ │ TIER 2: REGIONALIZATION (Medium-term — days/weeks) │ │ → Partitions the fulfillment network into autonomous zones│ │ → Ensures 70-80% of orders are fulfilled intra-region │ ├─────────────────────────────────────────────────────────────┤ │ TIER 3: CONDOR (Short-term — hours) │ │ → Continuously re-optimizes the fulfillment plan within │ │ a 5-6 hour window before pick-and-pack begins. │ └─────────────────────────────────────────────────────────────┘ Anticipatory Shipping — Shipping Before You Buy A Crazy but Effective Idea Amazon holds a patent (US Patent 8,615,473) describing a system that begins shipping items BEFORE a customer places an order . It sounds like science fiction, but it's a reality. Traditional Model: Customer orders → Warehouse processes → Ships → Delivered (2-5 days) Anticipatory Shipping: ML predicts: "Customers in Region X will buy 200 iPhone 16s in the next 3 days" → Amazon ships 200 iPhones from a central hub to local delivery hubs in Region X → Customer places order → The item is already locally staged → Delivered same-day! ML Model Input Features Input Feature Significance Purchase history What do they buy, and how often? Browsing behavior What are they looking at? Cart abandonment? Wishlists Explicitly desired items Seasonal patterns Winter coats in November, sunscreen in June Regional demographics High-income areas? Young families? College towns? Trending products Items going viral on social media Weathe

2026-06-18 原文 →
AI 资讯

42/60 Days System Design Questions

Your AI agent remembered the user's name. Then it forgot what it was doing. Here's the setup: User asks the agent: book the cheapest flight to NYC, search hotels under $150/night, then compare total trip cost. By step 3, the agent calls the LLM with 8,000 tokens of raw conversation history — and still answers as if it's turn 1. You need a memory architecture before this ships. Which one do you pick? A) In-context window only — full conversation stays in the system prompt. Simple. Breaks at ~15 turns or 8K tokens, whichever comes first. B) Vector memory store — embed past turns, retrieve the top-k by semantic similarity at query time. Works great until "NYC flight" pulls a memory about a past NYC trip instead of the current task. C) Episodic memory with summarization — compress old turns into structured event summaries, inject the relevant ones per request. More complex to build. Much harder to confuse. D) Redis session state — structured key-value store, explicit agent reads/writes. Deterministic. Requires the agent to know what to store and when. One of these collapses past 15 turns. One retrieves the wrong context at exactly the wrong moment. One is the right answer for task-oriented agents. Pick A, B, C, or D — and tell me where you've hit this in production. Full breakdown in the comments.

2026-06-18 原文 →
AI 资讯

Your Nouns Are Not Your Architecture

A common way to design an application is to begin with its nouns: User Product Order Payment Then each noun receives the standard architectural starter pack: UserController UserService UserRepository The controller receives users, the service services them, and the repository stores them somewhere responsible. This is noun-oriented architecture : treating every important thing in the domain as if it were automatically a useful software boundary. It works for simple CRUD systems. Unfortunately, most applications eventually do something. The noun becomes a drawer Consider a typical UserService : register() findByEmail() resetPassword() changeAddress() disableAccount() mergeAccounts() assignRole() calculateDiscount() These operations all involve a user. That is approximately where their similarity ends. They have different rules, dependencies, side effects, security concerns, owners, and reasons to change. They live together because User was the nearest available noun when the folders were created. As more behaviour accumulates, UserService becomes the official location for anything vaguely user-shaped. Other components depend on it. It gradually depends on authentication, email, permissions, billing, auditing, and several services added during incidents nobody wishes to revisit. The noun becomes both a dependency of everything and a consumer of everything. The folder remains impressively tidy. Name the capability, not the material A better starting question is not: What things exist in this system? It is: What must this system be capable of doing? That leads to components such as: UserRegistrar PasswordResetter AccountMerger OrderPlacer PaymentRefunder SubscriptionCanceller These are agentive names . They name the component responsible for performing a capability. Compare: UserService with: PasswordResetter UserService tells us which noun is nearby. PasswordResetter tells us what the component is for. That difference produces better architectural questions: What rules

2026-06-18 原文 →
AI 资讯

REST vs GraphQL vs gRPC — Which One Should You Actually Use?

Every engineering team hits this conversation at some point. Someone proposes GraphQL. Someone else says REST is fine. A third person mentions gRPC and half the room goes quiet. The debate usually ends with the most senior person in the room picking what they're most familiar with. That's not a strategy — that's habit. Here's an objective breakdown of all three, when each one wins, and how to actually make the decision for your specific use case. The Core Mental Model Before comparing them, understand what each one is optimizing for: REST optimizes for simplicity and broad compatibility GraphQL optimizes for flexibility and precise data fetching gRPC optimizes for performance and strongly-typed contracts None of them is universally better. Each one is a tradeoff. The right answer depends entirely on who is consuming your API and what they need from it. REST — The Default That Still Wins Most of the Time REST (Representational State Transfer) is not a protocol. It's an architectural style built on HTTP — verbs, URLs, and status codes most developers already understand. Where REST genuinely wins: Public APIs. If external developers are consuming your API, REST is the only reasonable default. The tooling, documentation patterns, and developer familiarity are unmatched. Stripe, Twilio, GitHub — all REST. Simple CRUD services. If your resource model is straightforward, REST maps cleanly to it. No overhead, no learning curve, no ceremony. Browser-native requests. REST over HTTP works directly in the browser without any special client. Fetch it, done. Where REST struggles: Over-fetching and under-fetching. A single REST endpoint returns a fixed shape. Mobile clients that need 3 fields get 40. Separate data needs often require multiple round trips. Versioning overhead. As covered in our previous post — every breaking change forces a versioning decision. This compounds quickly on complex APIs. GraphQL — Powerful, But You Need to Earn It GraphQL is a query language for your A

2026-06-16 原文 →
AI 资讯

Build an AI Pipeline FastAPI + Kafka + Workers

Most AI demos work perfectly on a laptop. But production AI systems can become fragile when everything is handled inside one synchronous API call. A user sends a request. The API extracts text. The API chunks the content. The API generates embeddings. The API stores data. The API waits for everything to finish. This may look simple in a demo, but it quickly becomes a problem in real systems. The problem with one giant API call In many AI applications, the API is expected to do too much. For example, in a document processing or RAG pipeline, one request may trigger multiple heavy steps: text extraction chunking embedding generation indexing summarization database updates If all of this happens inside one synchronous request, the API becomes slow and fragile. If one downstream step fails, the complete request may fail. If traffic increases suddenly, the API may become overloaded. This is why event-driven architecture becomes useful for AI workloads. A better approach: API + Kafka + workers Instead of making the API do everything, we can split the workflow into smaller services. The API accepts the request and publishes an event. Background workers consume events and continue the processing asynchronously. A simple flow looks like this: User Request ↓ FastAPI ↓ Kafka / Redpanda Topic ↓ Python Worker ↓ Next Processing Stage In my practical demo, I am using: FastAPI Redpanda Python workers Docker Compose Kafka-compatible messaging Why Redpanda? Redpanda is Kafka-compatible, which makes it useful for local demos and event-driven architecture experiments. It allows us to work with Kafka-style topics, producers, and consumers while keeping the setup simple for development. What this architecture gives us This approach helps with: decoupling services handling bursty workloads moving long-running tasks to background workers improving scalability isolating failures building production-style AI pipelines This pattern is especially useful for AI systems involving: document proce

2026-06-16 原文 →
AI 资讯

[System Design] Ride-Hailing Dispatch Algorithm: How Uber DISCO & Grab DispatchGym Match Drivers

Every time you tap "Book Ride," a system makes dozens of decisions in under two seconds: Which driver? What route? What's the real ETA? This article breaks down exactly how the dispatch algorithm works — from the greedy approach that fails at scale, to the bipartite graphs, batched matching, and surge pricing mechanics that power Uber, Lyft, Grab, and Gojek today. Why a Greedy Dispatch Algorithm Fails (Closest Driver Problem) The first instinct when designing a matching system is to pair every customer with their nearest driver. However, this Greedy approach causes massive losses at a system-wide scale: Example: 3 riders (R1, R2, R3) and 3 drivers (D1, D2, D3) Greedy Matching (closest driver): R1 ← D1 (ETA 2 mins) ✓ R2 ← D3 (ETA 8 mins) ← D2 was "taken" by R1, even though D2 is closer to R2 R3 ← D2 (ETA 10 mins) ← Terrible outcome Total ETA: 2 + 8 + 10 = 20 minutes Optimal Matching (global optimal): R1 ← D2 (ETA 3 mins) R2 ← D1 (ETA 3 mins) R3 ← D3 (ETA 4 mins) Total ETA: 3 + 3 + 4 = 10 minutes ← 50% better! Uber refers to this problem as Global Optimization — finding an assignment strategy that minimizes the total ETA of the entire system , rather than optimizing just for individual pairs. Bipartite Graph Matching: The Mathematical Foundation (Lyft) Before diving into the systems, it helps to understand the mathematical model that all ride-hailing matching engines share at their core. Lyft formalizes dispatch as a bipartite graph matching problem : Bipartite Graph: Set A (Riders): { R1, R2, R3, R4 } Set B (Drivers): { D1, D2, D3, D4, D5 } Edges: every possible Rider ↔ Driver pair Edge Weight: cost of that match (e.g., ETA, driver rating, distance) Goal: Find a set of edges (a "matching") where: - No rider is matched to more than one driver - No driver is matched to more than one rider - The total cost of all selected edges is minimized This is known as the Minimum Weight Bipartite Matching problem. The classical algorithm for solving it is the Hungarian Algorithm (

2026-06-15 原文 →
AI 资讯

HLD Fundamentals #1: Network Protocols

Network Protocols Network protocols define how computers communicate over a network. Whether you're opening Instagram, sending a WhatsApp message, watching Netflix, or transferring money through a banking app, some protocol is working behind the scenes to make communication possible. Client-Server Model What is it? The Client-Server model is a communication architecture where: Client requests a service or data. Server processes the request and returns a response. Most modern applications follow this architecture. How Does It Work? Client ---------- Request ----------> Server Client <--------- Response ---------- Server The client always initiates communication, and the server listens for incoming requests. Real World Example Instagram When you open Instagram: Mobile app sends a request. Instagram servers process the request. Feed data is fetched from databases. Posts are returned to your phone. Instagram App | V Instagram Server | V Database Advantages Centralized control Easier security management Easy maintenance Easier data consistency Disadvantages Server can become a bottleneck Single point of failure if not replicated Interview One-Liner Client-Server architecture is a centralized model where clients request resources and servers provide them. Peer-to-Peer (P2P) Model What is it? In a Peer-to-Peer network, every machine can act as both: Client Server There is no central server controlling communication. How Does It Work? Peer A <------> Peer B ^ ^ | | V V Peer C <------> Peer D Each peer can directly share resources with others. Real World Example BitTorrent Instead of downloading a file from one server: User | +--> Peer 1 | +--> Peer 2 | +--> Peer 3 Different parts of the file are downloaded from multiple peers simultaneously. Blockchain Bitcoin and Ethereum networks operate using Peer-to-Peer communication. Advantages Highly scalable No central server cost Better fault tolerance Disadvantages Harder to manage Security challenges Data consistency issues Inter

2026-06-14 原文 →
AI 资讯

From Scaling Data to Transcribing Voices: Building Resilience Under Pressure

As my backend engineering internship wraps up, I’ve been reflecting on the tasks that pushed me the hardest. Building minimum viable products is one thing, but making them resilient, scalable, and fault-tolerant is an entirely different beast. Here are two of the most memorable tasks from my time here—one solo dive into system scaling, and one team effort tackling asynchronous voice processing. Task 1: Scaling the Insighta Labs+ Query Engine (Individual) What it was Insighta Labs+ is a demographic intelligence platform where analysts and engineers run structured queries on user profiles via a CLI and a Web Portal (backed by GitHub OAuth and RBAC). My task was to take a functional MVP and evolve it into a robust query engine capable of handling tens of millions of records and hundreds of concurrent queries per minute. The problem it was solving The initial architecture worked flawlessly for a few thousand records, but under scale, it started showing cracks. Latency : Without indexing, every filter query triggered a full-table scan. Redundancy : Identical queries from different users wasted CPU and DB cycles. Write-Pressure : Users needed to bulk-upload CSVs containing up to 500,000 rows. Processing these synchronously locked the database, bringing read operations to a halt. How I approached it Instead of blindly throwing more server power at the problem, I focused on doing less work. Targeted Indexing : I added indexes only to frequently filtered columns. Caching & Normalization : I introduced Redis for TTL-based caching. To maximize cache hits, I built a query normalization layer. Whether a user queried "young males" or "men under 30" , the parser normalized the filter object into a canonical form before hashing the cache key. Connection Pooling : I set up PgBouncer to manage database connections and prevent exhaustion under high concurrency. Chunked Ingestion : For the massive CSV uploads, I implemented chunked streaming. Rows were validated individually; valid row

2026-06-13 原文 →
AI 资讯

Building Taocarts’ Anti-Fraud Risk Control System: Eliminating Malicious Exploitation of Coupons, Points, and Promotions

Cross-border purchasing platforms commonly use marketing tactics such as coupons, registration points, order rebates, and spend-based discounts to acquire new users and boost engagement. However, public promotions are prime targets for “wool hunters” (fraudsters) who exploit batch account registration, fake orders, malicious order spamming, and combined discount abuse to drain platform benefits, causing direct financial losses. Most purchasing systems lack dedicated event risk controls, making them highly vulnerable to batch exploitation as soon as a promotion goes live. This not only leads to financial losses but also crowds out genuine user benefits and distorts campaign effectiveness. This article details Taocarts’ comprehensive anti-fraud risk control framework, which uses multi‑dimensional behavior detection, rule‑based blocking, and account risk assessment to accurately distinguish real users from malicious exploiters, ensuring fair and controllable marketing activities. First, we identify common malicious exploitation scenarios and system vulnerabilities in cross‑border platforms: Batch account registration – Using new‑user exclusive coupons and registration points to harvest benefits repeatedly. Fake order placement and cancellation – Repeatedly claiming limited‑time discounts or rebates by placing and then canceling orders. Multiple accounts from the same device/IP – Spamming orders to consume activity quotas. Illegal discount stacking – Violating platform rules by combining multiple coupons or point deductions. Activity volume manipulation – Generating fake orders to earn activity rewards or points, creating false engagement data. Traditional systems have no risk rules and cannot detect batch operations or abnormal behavior, leading to wasted marketing spend and campaigns that actually lose money. Taocarts builds a fine‑grained anti‑exploit rule engine based on four dimensions: user behavior, device information, network characteristics, and order data, ena

2026-06-11 原文 →
AI 资讯

I Built My Own API Gateway in Rust — Here's What I Learned

Every backend project I've worked on eventually hits the same wall. You start clean — one service, simple routes, everything works. Then slowly the requirements creep in. "We need rate limiting." "Can we add auth middleware?" "What happens when the user service goes down — does it take everything else with it?" You either bolt these things onto every service individually, copy-paste the same middleware across projects, or pay for a managed gateway like Kong or AWS API Gateway and hope it does what you need. I wanted to actually understand how these things work under the hood. So I'm building one — and this is what I've learned so far. What is Ferrox? Ferrox is a self-hosted, programmable API gateway written entirely in Rust. It sits in front of your backend services and handles everything a production system needs in one place: Dynamic routing — point any path prefix to any upstream service Authentication — JWT and API key validation on protected routes Rate limiting — Redis-backed per-IP and per-API-key limiting Circuit breaking — stops hammering a dead upstream service Response caching — Redis-backed TTL cache per route Real-time observability — WebSocket dashboard with live request stats Prometheus metrics — plug straight into Grafana The idea is simple. Instead of this: Client → Service A (has its own auth, rate limiting, logging) Client → Service B (has its own auth, rate limiting, logging) Client → Service C (has its own auth, rate limiting, logging) You get this: Client | v FERROX (auth, rate limiting, circuit breaking, logging — once) | +--------+--------+ | | | Svc A Svc B Svc C (clean) (clean) (clean) Your services stay clean. Ferrox handles the cross-cutting concerns. Why Rust? Honest answer — I already knew Rust from my backend work. But for a gateway specifically, it felt like the obvious choice. A gateway sits on the critical path of every single request. Every millisecond of latency it adds is latency your users feel. You need predictable performance

2026-06-10 原文 →
AI 资讯

Implementing Token Bucket Rate Limiting for High-Volume Inventory APIs

When you expose inventory or checkout endpoints to public-facing front-ends or third-party webhooks, safeguarding those APIs from brute-force scripts, scraping bots, and inventory hoarding algorithms becomes a critical requirement. Without defensive rate limiting, a single coordinated script can easily overwhelm your database connections. The Problem with Simple Counter Resets A common mistake when setting up basic API protection is using a rigid "Fixed Window" counter (e.g., allowing 100 requests per minute, resetting exactly at the turn of the clock). This creates a massive flaw where a developer can flood your server with 100 requests at 11:59:59 and another 100 requests at 12:00:01, effectively doubling your acceptable burst traffic and causing severe performance dips. To handle uneven burst traffic safely without crashing your database, the standard approach is implementing a token bucket algorithm. The Token Bucket Pattern The token bucket algorithm maintains a centralized bucket that holds a maximum capacity of tokens. Tokens are added back to the bucket at a constant, predictable rate over time. Each incoming API request consumes exactly one token. If the bucket is completely empty, the request is instantly rejected with a 429 Too Many Requests status code, protecting your core server threads. javascript // Quick Redis-based token bucket rate limiter concept async function isRateLimited(userId) { const key = `rate:${userId}`; const now = Date.now(); // Use a Redis multi-exec transaction to atomically check and update tokens const [tokens, lastRefill] = await redis.hmget(key, 'tokens', 'lastRefill'); // Calculate token replenishment based on time elapsed... // Return true if tokens <= 0, otherwise decrement tokens and update timestamp }

2026-06-10 原文 →
AI 资讯

Hashing in Distributed Systems: A Complete Guide to Algorithms, Best Practices, and Real-World Applications

Have you ever wondered how Discord keeps your channel messages available even when a server goes down? Or how Amazon DynamoDB serves petabytes of data with single-digit millisecond latency? The unsung hero powering almost all these distributed systems is hashing — a simple but powerful technique that makes even load distribution, fast lookups, and seamless scaling possible. As more applications move to distributed cloud architectures, understanding hashing for distributed systems is no longer optional for developers. Choosing the wrong hashing algorithm can lead to cascading failures, cache stampedes, and expensive downtime. This guide breaks down every core hashing technique, real-world use cases, best practices, and common pitfalls to avoid in 2026. Table of Contents What is Hashing in Distributed Systems? Core Hashing Algorithms Explained Traditional Modulo Hashing Consistent Hashing Virtual Nodes (VNodes) Rendezvous Hashing (HRW) Jump Consistent Hash Maglev Hashing Multi-Probe Consistent Hashing Consistent Hashing with Bounded Loads Real-World Applications of Distributed Hashing Head-to-Head Algorithm Comparison Best Practices for Distributed Hashing Common Pitfalls to Avoid Conclusion References What is Hashing in Distributed Systems? Hashing in distributed systems is the practice of mapping data keys (e.g., user IDs, object keys, channel IDs) to server nodes using a deterministic hash function. The core goals are: Distribute load evenly across all nodes to avoid hotspots Enable fast lookups (O(1) or O(log N)) without a central coordinator Minimize data movement when nodes are added or removed during scaling Support fault tolerance by simplifying replication across nodes The simplest implementation is modulo-based hashing , where node_id = hash(key) % N and N is the total number of nodes. While trivial to implement, it suffers from a fatal flaw: the rehashing problem. When N changes (a node is added or removed), nearly all keys are remapped to new nodes, causin

2026-06-09 原文 →
AI 资讯

The Letter VCs Are Quietly Deleting from ARR

The Letter VCs Are Quietly Deleting from ARR Startups are reporting revenue they haven't earned yet. VCs know it. Investors are cheering anyway. We've seen this movie. You're evaluating an AI startup. The pitch deck shows $100 million in ARR. The growth curve is parabolic. The deck says they signed $100 million. What it doesn't say is that $70 million of that is "committed ARR": contracts signed but not yet invoiced, customers who haven't deployed yet, pilots that count toward the number if they convert. Subtract the gap and you've got $30 million in actual recognized revenue hiding under a $100 million headline. This is the ARR inflation playbook, and it's running at full speed right now. The Trick Has a Name "CARR" stands for Contracted or Committed ARR. It's a legitimate concept. In industries where revenue accrues slowly after contract signing (healthcare AI deployments, energy optimization platforms, multi-year enterprise integrations), the gap between signature and recognition can legitimately take months or years to close. Reporting CARR alongside ARR, properly labeled, is defensible. That's not what's happening. What's happening is simpler: founders strip the "C" and just call it ARR. One VC told TechCrunch the gap between CARR and actual ARR can run as high as 70% [1]. In some confirmed cases the spread is 3-5x. Another investor said flatly: "For sure they are reporting CARR as ARR" [1]. The article indicates that the investor community is not only aware, but many are actively complicit. The logic follows its own warped rationality. When one startup in a category inflates, the others have to follow to stay competitive for talent and headlines. "When one startup does it in a category, it is hard not to do it yourself just to keep up," as one investor put it [1]. Spellbook CEO Scott Stevenson, one of the few willing to call this in public, described the practice as a "huge scam," adding that major VC funds are not just watching it happen but actively supporti

2026-06-08 原文 →
AI 资讯

32/60 Days System Design Questions!

Your startup just got its first SOC 2 audit. The auditor asks: "Where are your database passwords, API keys, and service tokens stored?" Your senior engineer goes quiet. Turns out half of them are in .env files committed to git 18 months ago. Three are hardcoded in Lambda environment variables. One is in a Slack message from 2023. You have 6 services in production, 4 environments, and zero rotation policy. Here's the setup: • NestJS API → Postgres (password in env var) • NestJS API → Stripe (API key in env var) • Background workers → SQS, S3 (AWS credentials in env var) • 3rd-party webhooks → HMAC secrets in env var • Zero rotation. Zero audit trail. Zero centralized access control. You need to fix this. And you can't take downtime. A) Move everything to AWS Secrets Manager — SDK calls at runtime, IAM controls access, auto-rotation built in. B) Use HashiCorp Vault — dynamic secrets, fine-grained policies, works across any cloud or on-prem. C) Use environment variables injected at deploy time via CI/CD — secrets stored in GitHub Actions / GitLab CI secrets vault, never touch disk. D) Encrypt secrets with KMS and store ciphertext in your own database — decrypt at runtime, full control. All four are used in production at real companies. Pick one — A, B, C, or D — and tell me why. I'll drop the full breakdown in the comments. If your team is having this argument right now, share this post. Someone needs to see it. Drop your answer 👇 30DaysOfSystemDesign #SystemDesign #BackendEngineering #CloudArchitecture

2026-06-08 原文 →
AI 资讯

Road To KiwiEngine #12: Why I Want To Build Hardware Again

Somewhere along the way, computing became disposable. Devices became sealed. Systems became rented. Ownership became licensing. Repairability disappeared. Infrastructure moved away from the user and into distant cloud platforms. And I think we lost something important because of it. Lately, I’ve found myself becoming increasingly interested in hardware again. Not just software. Not just cloud systems. But actual computing devices. Servers. Home infrastructure. Repairable machines. Set-top systems. Local AI appliances. Sovereign computing. Because I believe the next era of computing will belong to people who own their infrastructure again. The Provider Box Realization One thing that kept sticking in my head was this: Almost every home in America already has a provider box. A Comcast box. An AT&T gateway. A router. A modem. A streaming box. People are already comfortable with the idea of a dedicated computing appliance sitting in their home quietly powering their digital life. That realization changed how I thought about computing infrastructure. What if those boxes worked for the user instead of the provider? What if they: hosted local AI, managed home storage, coordinated smart devices, powered media systems, handled automation, protected privacy, synchronized intelligently, and operated as sovereign infrastructure? That idea became part of the thinking behind KiwiHome. The Return Of Home Infrastructure For a long time, the industry moved toward centralization. Everything shifted toward: SaaS, subscriptions, streaming, cloud storage, cloud intelligence, and rented operational environments. Convenient? Absolutely. But also fragile. If: pricing changes, services disappear, companies shut down, APIs get revoked, or platforms change policies, entire workflows collapse overnight. I think people are starting to feel that tension. Especially creators. Especially businesses. Especially technical users. That’s why I believe we’re going to see a major resurgence in: home serv

2026-06-08 原文 →
AI 资讯

Architecting Strict Sequential Ordering in a Concurrent World

Imagine you are building a cloud-native backend for a high-frequency trading platform or a core banking ledger. To ensure mathematical immutability and prevent silent data tampering, compliance mandates that every transaction for a specific financial account must be cryptographically chained. This means the signature of Transaction #50 must explicitly include the cryptographic hash of Transaction #49. You cannot sign them out of order, and the backend is strictly responsible for generating and validating this chain. This introduces a massive distributed systems headache: How do you enforce strict, sequential ordering while maintaining the concurrency required to scale a modern cloud architecture? Let's walk through the evolution of this system, deconstruct exactly how the standard event-driven approach fails in production, and examine the Staff-level architecture required to fix it. Phase 1: The MVP & The Database Bottleneck In the early days, traffic is low. An account might see one transaction every few minutes. The "Happy Path" is simple: The API receives a deposit request for Account A. The API queries Postgres for the last_signature_hash . The API computes the new hash in memory: SHA(last_hash + new_transaction_data) . The API writes the new transaction and updates the state. The Pitfall: The Thundering Herd To prevent two concurrent requests from reading the same previous hash, you wrap the database operation in a pessimistic lock: SELECT ... FOR UPDATE . This forces the database to serialize requests at the row level. When a massive partner bank initiates a bulk sync, dumping 5,000 transactions for a single corporate account onto the API in two seconds, 4,999 concurrent threads immediately hit the FOR UPDATE lock and block. The database connection pool is instantly exhausted, latency spikes platform-wide, and the MVP dies. The Insight: The database must be your last line of defense, not your primary queueing mechanism. Contention must be solved upstream in me

2026-06-07 原文 →
AI 资讯

Your Codebase Is a Mess Because Your Team Can't Agree on What a "Customer" Is

Nobody wants to hear this. But the reason your software is hard to change, hard to test, and hard to explain to a new engineer isn't your tech stack. It's that your code doesn't reflect how your business actually works. Your engineers are using one word — "customer," "order," "student," "subscriber" — and meaning six different things depending on which part of the system they're touching. Your domain expert says "order" and means something completely different from what your database schema says "order" is. That gap? That's where complexity lives. That's where bugs are born. That's where senior engineers spend their Fridays. Domain-Driven Design is the discipline of closing that gap. Here's what it actually means, practically, without the academic noise. The Core Problem: One Model Trying to Mean Everything Imagine a map that tried to show subway routes, underwater hazards, hiking trails, and flight paths — all at once. It would be useless. A subway map works because it only shows what matters for navigating trains. A nautical chart works because it only shows what matters for sailing. Each map is an abstraction built for a specific purpose, valid within a specific context. Your software models need to work the same way. The moment you build a single "Customer" class that has to satisfy your billing team, your marketing team, your support team, and your logistics team simultaneously — that class becomes a bloated, ambiguous disaster. Everyone adds their fields. Nobody removes anything. The model stops meaning anything specific to anyone. This is the monolithic model trap. And most large codebases are sitting right inside it. Strategic Design: Understand the Problem Before You Touch Code DDD separates design into two layers. Strategic design comes first — it's the work you do before writing a single line of code. Step 1: Find Your Subdomains A subdomain is a slice of the business problem. Ordering. Shipping. Notifications. Payments. Inventory. These aren't your micro

2026-06-07 原文 →