KoreaDevKNOWLEDGE SHARING

Content typeLearn

AI SOFTWARE DEVELOPMENT · 08 / 10

High-performance systems and language choices

Compare TypeScript, Python, Go, and Rust by latency, throughput, memory safety, ecosystem, and cost of change, not by trends.

Difficulty
Practical
Structure
Lessons 8 · Labs 2 · Assessment

CORE UNIT 1 / 1

High-performance systems and language choices

Compare TypeScript, Python, Go, and Rust by latency, throughput, memory safety, ecosystem, and cost of change, not by trends.

Difficulty
Practical
Structure
Lessons 8 · Labs 2 · Assessment

Diagrams and tables: composed by the author using each lesson's official primary sources. Find the originals and review dates at the end of that lesson.

NEW HIRE ONBOARDING

Start in the order you would receive your first assignment

So that even a new hire with no prior IT background can follow along, we start with the situation, the task, the evidence, and when to report, before difficult definitions.

  1. 01

    Read the situation in one sentence

    The React product's API mostly waits for the database and LLM, while one PDF parser continuously uses 4 CPU cores. The team is familiar with TypeScript and Python.

  2. 02

    Today's assignment

    Compare the four languages on common axes of workload and failure cost.

  3. 03

    Evidence that shows the work is complete

    Apply returned offsets to mixed-script input and verify byte/character units and error-handling contracts.

  4. 04

    When to stop and ask a senior colleague

    An unrepresentative workload or microbenchmark distorts production conclusions.

Unpack unfamiliar terms first

Measure workload before language
Selecting a language for performance starts with actual bottlenecks that prevent meeting user SLOs and the cost of change, not benchmark rankings.
TypeScript: Web, Agent, and MCP contracts
TypeScript's strength lies in connecting the browser and Node ecosystems, structural typing, and fast feedback within the same product boundary.
Python: AI, data, and rapid experimentation
Python's AI libraries and expressiveness make experimentation and service integration fast, but you need to understand the execution model for each workload.

Questions for this course

Why did it change, and what must be verified?

Do not merely memorize a technology's advantages; check the conditions under which they hold and the new failure boundaries they introduce.

OBSERVABLE OUTCOMES

What you can do after this course

  1. Compare the four languages on common axes of workload and failure cost.
  2. Explains the real boundaries of Python async and CPU parallelism, Go concurrency, and Rust ownership.
  3. Choose service boundaries based on benchmark and profile evidence.

PREREQUISITE CHECK

Three things to check before reading

This is not a test of memorized answers. Think about each question first, then open the explanation to review the foundational concepts used in this course.

1Does switching to a faster language make the whole service faster by the same ratio?

If time spent on network, database, or model inference remains unchanged, overall improvement is limited. First profile the workload to measure the bottleneck's share.

2Are concurrency and parallelism the same?

Concurrency structures the progress of multiple tasks, while parallelism actually performs multiple computations at the same instant. Async I/O is effective for the former but does not automatically guarantee parallel CPU computation.

3Is performance the only factor in choosing a language?

Correctness, libraries, hiring, build and deploy, observability, and speed of change also count toward total cost.

TEXTBOOK GUIDE

Main text that covers each concept from its background to the criteria for judging it

We explain the material section by section so readers new to IT can connect causes and effects without memorizing terms.

CONCEPT FLOW

How the chapters connect

The chapters are not isolated short answers to memorize. Follow them from left to right to see how each chapter's concepts support the next decision.

  1. 1.Measure workload before language
  2. 2.TypeScript: Web, Agent, and MCP contracts
  3. 3.Python: AI, data, and rapid experimentation
  4. 4.Go: Gateway · Concurrency · Operational simplicity
  5. 5.Rust: Memory safety and high-cost boundaries
  6. 6.Measure transfer costs before moving fast computation into another service
  7. 7.Define queue limits and cancellation completion before adding concurrency
  8. 8.Separate memory safety from business-input validation
High-performance systems and language choices: the overall map. If you lose track while reading the detailed explanations and chapters below, return to this sequence.
Figure 8-1. High-performance systems and language choices: concept developmentShows how each chapter’s choices and limits lead to the problems of the next chapter.
  1. 1
    Measure workload before language

    Selecting a language for performance starts with actual bottlenecks that prevent meeting user SLOs and the cost of change, not benchmark rankings.

  2. 2
    TypeScript: Web, Agent, and MCP contracts

    TypeScript's strength lies in connecting the browser and Node ecosystems, structural typing, and fast feedback within the same product boundary.

  3. 3
    Python: AI, data, and rapid experimentation

    Python's AI libraries and expressiveness make experimentation and service integration fast, but you need to understand the execution model for each workload.

  4. 4
    Go: Gateway · Concurrency · Operational simplicity

    Go offers fast compilation, single binaries, and goroutines that make network services simple to deploy.

  5. 5
    Rust: Memory safety and high-cost boundaries

    Rust ownership checks memory usage rules at compile time to reduce certain errors, but it carries learning and integration costs.

  6. 6
    Measure transfer costs before moving fast computation into another service

    A language boundary slows the request if added serialization, copying and waiting outweigh computation savings.

  7. 7
    Define queue limits and cancellation completion before adding concurrency

    Concurrency must be evaluated against downstream capacity and resources reclaimed after cancellation.

  8. 8
    Separate memory safety from business-input validation

    Test ownership guarantees separately from input size, authorization and error handling.

CONTROLLED EXPLANATION

Account for the 90ms added by a language boundary

Current state: Same input and accuracy

Account for the 90ms added by a language boundary

Source: an author-designed hypothetical calculation based on language execution principles, not measured product performance.

Measure baselineMove compute boundarySum call-boundary costsPlus the other 120msCompare whole requests1Same input and accuracy2Existing request: 200ms3New computation: 20ms4Transfer cost: 90ms5Candidate request: 230ms
  1. Same input and accuracy

    Compare whole-image-request latency.

  2. Existing request: 200ms

    Computation 80ms + other work 120ms

  3. New computation: 20ms

    Looking only at the fast function, it appears to be an improvement.

  4. Transfer cost: 90ms

    Adds transfer and reconstruction overhead.

  5. Candidate request: 230ms

    Latency grows to 20 + 90 + 120.

1 → 2
Measure baseline
1 → 3
Move compute boundary
3 → 4
Sum call-boundary costs
4 → 5
Plus the other 120ms
2 → 5
Compare whole requests

Values are stage times for the same hypothetical request. Arrow labels distinguish comparison from addition.

CONCRETE CASES

Selection criteria for all courses

TABLE 8-1

Selection criteria for all courses

Compare the technology in each chapter by how it works, the new costs it adds, and the evidence to check, not by its name.

Table 8-1. High-performance systems and language choices: design decision criteria
.Core mechanismCosts to watchEvidence to check
1. Measure workload before languageProfiles and benchmarks quantify the share of time and resources that can be optimized.An unrepresentative workload or microbenchmark distorts production conclusions.Combine the production trace's time share with a benchmark under the same conditions to calculate the upper bound on expected overall improvement.
2. TypeScript: Web, Agent, and MCP contractsStatic checkers and the JavaScript ecosystem provide fast feedback on end-to-end product changes.The costs are runtime type gaps, event-loop blocking, and dependency supply chain risk.Observe event-loop lag, type bypass, and invalid HTTP input separately.
3. Python: AI, data, and rapid experimentationA coroutine yields control at I/O wait points, allowing one thread to coordinate many connections.Limitations include CPU-bound work, blocking libraries, and the fact that type hints are not enforced at runtime.Run I/O waits and CPU loops in the same event loop and compare throughput and lag.
4. Go: Gateway · Concurrency · Operational simplicityThe runtime scheduler multiplexes many goroutines onto OS threads, and the goroutines cooperate through channels and context.The costs are races, goroutine leaks, backpressure, and ecosystem fit.Measure worker count and tail latency with the race detector, under cancellation, and at queue saturation.
5. Rust: Memory safety and high-cost boundariesThe compiler checks value ownership, lifetimes, and thread-safety traits and rejects invalid memory use.Costs include the learning curve, compile time, FFI, and ecosystem choices.Use memory and CPU profiles and interface contracts to compare latency and errors before and after introducing the Rust boundary.
6. Measure transfer costs before moving fast computation into another serviceMeasuring both sides of a boundary reveals whether computation savings offset transfer costs.Independent scaling and failure isolation come with copying, networking and version-management costs.Calculate the 200ms and 230ms figures for the hypothetical request, and build a table for measuring the same stages in real candidates.
7. Define queue limits and cancellation completion before adding concurrencyAdmission control communicates downstream limits upstream, while cancellation cleanup removes unnecessary waiting.Early rejection increases immediate failures for some requests but can prevent queue collapse.In the 10-connection, 100-request scenario, verify that tasks and connections return to baseline after cancellation.
8. Separate memory safety from business-input validationSeparating lifetime rules from input semantics reveals boundary errors outside compiler checks.Performance gains come with deployment combinations, error conversion and calling-contract maintenance.Apply returned offsets to mixed-script input and verify byte/character units and error-handling contracts.

CHAPTER 1 / 8

Measure workload before language

Selecting a language for performance starts with actual bottlenecks that prevent meeting user SLOs and the cost of change, not benchmark rankings.

Why this concept became necessary

Break request latency into network, queue, application CPU, database, and model inference. If application CPU accounts for 5%, making that part twice as fast produces only a small overall improvement.

Comparisons are reproducible only when representative input, warmup, concurrency, percentiles, and resource limits are fixed. Looking only at averages can miss tail latency, memory pressure, and garbage collection pauses.

Figure 8-2. Measure workload before language: decision flowThe chain from the problem conditions through the working principle to verification evidence.
Problems and selection criteria

Selecting a language for performance starts with actual bottlenecks that prevent meeting user SLOs and the cost of change, not benchmark rankings.

How it works

Profiles and benchmarks quantify the share of time and resources that can be optimized.

Verification evidence

Combine the production trace's time share with a benchmark under the same conditions to calculate the upper bound on expected overall improvement.

Follow it through a concrete system

Changing languages merely because responses are slow can miss the actual bottleneck in network waits, database queries, model inference, or serialization. Break down end-to-end time using traces and measure CPU profiles, allocations, queues, and downstream capacity to identify the share attributable to application code. The maximum reducible share of elapsed time cannot exceed the share occupied by that bottleneck.

Representative workloads must include large payloads, concurrent users, and error conditions, not just average requests. Even if a parser is twice as fast in a microbenchmark, the change in user latency may be small if parsing accounts for only 5% of the full request. Compare rewrite decisions by total cost, including throughput, tail latency, library maturity, deployment complexity, the team’s review capacity, and incident-response time.

Selection criteria and failure boundaries

An unrepresentative workload or microbenchmark distorts production conclusions.

Misconceptions to avoid: Rewriting in a compiled language does not speed up network or model latency.

Verify it yourself

Combine the production trace's time share with a benchmark under the same conditions to calculate the upper bound on expected overall improvement.

What to judgeProfiles and benchmarks quantify the share of time and resources that can be optimized.

To summarize this chapter

Selecting a language for performance starts with actual bottlenecks that prevent meeting user SLOs and the cost of change, not benchmark rankings.

Official sources for this chapter

The technical facts in the text were reviewed against the following primary sources. The author reconstructed the diagrams and comparisons using these materials.

  1. OpenTelemetry, 「SignalsReview date 2026-08-28 · Scope Latest official documentation
  2. Anthropic, 「Demystifying Evals for AI AgentsReview date 2026-08-28 · Scope Latest official documentation

CHAPTER 2 / 8

TypeScript: Web, Agent, and MCP contracts

TypeScript's strength lies in connecting the browser and Node ecosystems, structural typing, and fast feedback within the same product boundary.

Why this concept became necessary

Using the same type tooling for frontend components, backend APIs, and MCP schemas makes contracts easier to explore and refactor. However, package versions, build outputs, and runtime validation still require management, and this does not make it the default choice for CPU-heavy loops.

A single event loop can coordinate many I/O operations efficiently, but long-running CPU work may block other requests. Add workers, separate services, or native boundaries only where measurements identify bottlenecks.

Figure 8-3. TypeScript: Web, Agent, and MCP contracts: decision flowThe chain from the problem conditions through the working principle to verification evidence.
Problems and selection criteria

TypeScript's strength lies in connecting the browser and Node ecosystems, structural typing, and fast feedback within the same product boundary.

How it works

Static checkers and the JavaScript ecosystem provide fast feedback on end-to-end product changes.

Verification evidence

Observe event-loop lag, type bypass, and invalid HTTP input separately.

Follow it through a concrete system

TypeScript makes it easy to share one type vocabulary across systems with many JSON boundaries, such as browser UIs, Node APIs, and MCP tool schemas. Using discriminated unions to separate success and error states, together with exhaustive checks, lets you find unhandled locations at compile time when a new state is added. IDE refactoring, which quickly shows the impact of large interface changes, is another important operational benefit.

However, running CPU-heavy parsing or image conversion directly on Node’s single event loop delays other requests as well. You can isolate that work in a worker, a queue, or a separate service, but doing so adds serialization and operating costs. When choosing TypeScript, use real profiles to confirm that the team-productivity and ecosystem benefits still meet the workload’s CPU, memory, and latency requirements.

Selection criteria and failure boundaries

The costs are runtime type gaps, event-loop blocking, and dependency supply chain risk.

Misconceptions to avoid: It is incorrect to assume that using TypeScript makes AI-generated code semantically safe and eliminates runtime errors.

Verify it yourself

Observe event-loop lag, type bypass, and invalid HTTP input separately.

What to judgeStatic checkers and the JavaScript ecosystem provide fast feedback on end-to-end product changes.

To summarize this chapter

TypeScript's strength lies in connecting the browser and Node ecosystems, structural typing, and fast feedback within the same product boundary.

Official sources for this chapter

The technical facts in the text were reviewed against the following primary sources. The author reconstructed the diagrams and comparisons using these materials.

  1. Microsoft, 「TypeScript HandbookReview date 2026-08-28 · Scope Latest official documentation
  2. Microsoft, 「Type CompatibilityReview date 2026-08-28 · Scope Latest official documentation

CHAPTER 3 / 8

Python: AI, data, and rapid experimentation

Python's AI libraries and expressiveness make experimentation and service integration fast, but you need to understand the execution model for each workload.

Why this concept became necessary

The Python ecosystem makes it easy to connect models, data science, and API tools such as FastAPI. Type hints and schema models improve contracts, but you still need to consider Python's runtime characteristics and the native-code boundaries of external libraries.

`asyncio` is suitable for cooperative concurrency, where other tasks can progress during I/O waits. CPU-bound Python code blocks the event loop, so consider processes, native libraries, queues, or a service in another language.

Figure 8-4. Python: AI, data, and rapid experimentation: decision flowThe chain from the problem conditions through the working principle to verification evidence.
Problems and selection criteria

Python's AI libraries and expressiveness make experimentation and service integration fast, but you need to understand the execution model for each workload.

How it works

A coroutine yields control at I/O wait points, allowing one thread to coordinate many connections.

Verification evidence

Run I/O waits and CPU loops in the same event loop and compare throughput and lag.

Follow it through a concrete system

Python's rich model libraries, notebooks, data-processing tools, and API frameworks let you quickly carry the same concepts from experiment to service. Type hints and validation libraries can document interfaces and catch some errors earlier, but type hints themselves do not enforce every value at runtime. If you do not lock package and native extension versions, the same code can behave differently across environments.

Asyncio lets other coroutines progress while waiting for network or disk I/O; it does not automatically parallelize CPU computation across cores. CPU-bound preprocessing may need a process pool, native library, or separate worker, and GPU work requires inspecting the framework's execution model and queue. Measure concurrency and memory copying for each workload instead of drawing a conclusion from the word GIL alone.

Selection criteria and failure boundaries

Limitations include CPU-bound work, blocking libraries, and the fact that type hints are not enforced at runtime.

Misconceptions to avoid: It is incorrect to assume that adding `async` automatically parallelizes CPU computation across multiple cores.

Verify it yourself

Run I/O waits and CPU loops in the same event loop and compare throughput and lag.

What to judgeA coroutine yields control at I/O wait points, allowing one thread to coordinate many connections.

To summarize this chapter

Python's AI libraries and expressiveness make experimentation and service integration fast, but you need to understand the execution model for each workload.

Official sources for this chapter

The technical facts in the text were reviewed against the following primary sources. The author reconstructed the diagrams and comparisons using these materials.

  1. Python Software Foundation, 「asyncio — Asynchronous I/OReview date 2026-08-28 · Scope Python 3.14 documentation

CHAPTER 4 / 8

Go: Gateway · Concurrency · Operational simplicity

Go offers fast compilation, single binaries, and goroutines that make network services simple to deploy.

Why this concept became necessary

A goroutine is a lightweight concurrent function, and channels structure communication. Neither removes races automatically, so shared memory, cancellation, timeouts, and bounded workers must still be designed.

Garbage collection and a relatively small language surface can benefit cloud service operations. However, Go has fewer options than Python for AI model libraries and rapid notebook experimentation, so it is better to split the boundary.

Figure 8-5. Go: Gateway · Concurrency · Operational simplicity: decision flowThe chain from the problem conditions through the working principle to verification evidence.
Problems and selection criteria

Go offers fast compilation, single binaries, and goroutines that make network services simple to deploy.

How it works

The runtime scheduler multiplexes many goroutines onto OS threads, and the goroutines cooperate through channels and context.

Verification evidence

Measure worker count and tail latency with the race detector, under cancellation, and at queue saturation.

Follow it through a concrete system

Go's goroutines and channels structure many network connections and cancellation with relatively simple syntax, which can suit gateways, controllers, and telemetry collectors. Single-binary deployment and quick startup reduce operational units. But creating unbounded numbers of lightweight goroutines lets producers outpace downstream consumers, fill queues and memory, and worsen tail latency.

Propagate context cancellation across every I/O boundary and design bounded concurrency, backpressure, and timeout budgets. Race detectors and profiles provide evidence about shared-state and allocation problems but do not replace production workloads. Judge Go by the current service's connection count, CPU share, and the team's operating experience, not merely its reputation as a “concurrency language”.

Selection criteria and failure boundaries

The costs are races, goroutine leaks, backpressure, and ecosystem fit.

Misconceptions to avoid: Creating more goroutines does not increase throughput without limit.

Verify it yourself

Measure worker count and tail latency with the race detector, under cancellation, and at queue saturation.

What to judgeThe runtime scheduler multiplexes many goroutines onto OS threads, and the goroutines cooperate through channels and context.

To summarize this chapter

Go offers fast compilation, single binaries, and goroutines that make network services simple to deploy.

Official sources for this chapter

The technical facts in the text were reviewed against the following primary sources. The author reconstructed the diagrams and comparisons using these materials.

  1. The Go Authors, 「Effective GoReview date 2026-08-28 · Scope Go official documentation

CHAPTER 5 / 8

Rust: Memory safety and high-cost boundaries

Rust ownership checks memory usage rules at compile time to reduce certain errors, but it carries learning and integration costs.

Why this concept became necessary

Ownership and borrowing prevent use-after-free and some data races at compile time without a garbage collector. Predictable memory use and native performance benefit high-throughput and safety-sensitive boundaries such as parsers, proxies, and inference extensions.

Rewriting every CRUD service in Rust can raise costs in libraries, development speed, and team capability. Placing a profiled hot path or a safety-critical component behind a small interface can deliver the benefit without a full rewrite.

Figure 8-6. Rust: Memory safety and high-cost boundaries: decision flowThe chain from the problem conditions through the working principle to verification evidence.
Problems and selection criteria

Rust ownership checks memory usage rules at compile time to reduce certain errors, but it carries learning and integration costs.

How it works

The compiler checks value ownership, lifetimes, and thread-safety traits and rejects invalid memory use.

Verification evidence

Use memory and CPU profiles and interface contracts to compare latency and errors before and after introducing the Rust boundary.

Follow it through a concrete system

Rust's ownership and borrowing reject some lifetime and sharing errors, such as dangling pointers and data races, at compile time. These guarantees can reduce failure and vulnerability risks at boundaries that process untrusted bytes at high speed, such as parsers, proxies, and inference extensions. Code using `unsafe` or FFI has different guarantees, so isolate it in small modules and review it separately.

Moving a profiled hot path behind a stable API into a Rust library or worker can reduce risk compared with rewriting the whole service. Benchmark end to end, including serialization, copying, and call overhead. Successful compilation does not establish correct business logic, authorization, or resistance to resource exhaustion, so maintain fuzzing, property tests, and operational limits together.

Selection criteria and failure boundaries

Costs include the learning curve, compile time, FFI, and ecosystem choices.

Misconceptions to avoid: It is incorrect to assume that using Rust eliminates logic bugs and all security vulnerabilities.

Verify it yourself

Use memory and CPU profiles and interface contracts to compare latency and errors before and after introducing the Rust boundary.

What to judgeThe compiler checks value ownership, lifetimes, and thread-safety traits and rejects invalid memory use.

To summarize this chapter

Rust ownership checks memory usage rules at compile time to reduce certain errors, but it carries learning and integration costs.

Official sources for this chapter

The technical facts in the text were reviewed against the following primary sources. The author reconstructed the diagrams and comparisons using these materials.

  1. The Rust Project, 「What Is Ownership?Review date 2026-08-28 · Scope The Rust Programming Language

CHAPTER 6 / 8

Measure transfer costs before moving fast computation into another service

A language boundary slows the request if added serialization, copying and waiting outweigh computation savings.

Why this concept became necessary

A function-only benchmark excludes the cost of a new service boundary. Packaging requests, sending them, and reconstructing results add time. First decide whether the unit for choosing a language is a function or a user request; only then is the comparison valid.

Serialization converts in-memory values into a transportable representation. Repeatedly copying large arrays can increase memory use and waiting even when computation is fast. Record payload size and boundary crossings to reveal costs hidden by small inputs.

An extension in the same process and a separate network service are different choices. The former may reduce call costs but requires considering failure isolation and deployment coupling. The latter permits independent scaling but introduces network failures and contract-version management.

Candidates must also produce equally correct results. A faster candidate that drops inputs or reduces precision changes more than the language. Fix tolerances, error responses and maximum input size before measuring total latency and resources.

Figure 8-7. Measure transfer costs before moving fast computation into another service: decision flowThe chain from the problem conditions through the working principle to verification evidence.
Problems and selection criteria

A language boundary slows the request if added serialization, copying and waiting outweigh computation savings.

How it works

Measuring both sides of a boundary reveals whether computation savings offset transfer costs.

Verification evidence

Calculate the 200ms and 230ms figures for the hypothetical request, and build a table for measuring the same stages in real candidates.

Follow it through a concrete system

Assume a teaching image-analysis request takes 80ms of computation and 120ms of other work, totaling 200ms. New computation takes 20ms but transfer and reconstruction add 90ms, making 230ms. The computation is faster while the user waits longer. State whether improvement is relative to the 80ms compute stage or the 200ms total to avoid misleading comparisons.

These are hypothetical teaching values, not product measurements. Compare batching small requests or computing in the existing process as separate candidates. If batching adds waiting, distinguish throughput gains from response latency. Record batch size for each experiment to distinguish added waiting from language-performance issues.

A counterexample is a compute-dominated task with a small input. The same transfer overhead can be worthwhile when computation savings are large enough. Locate the break-even point by input size rather than applying one conclusion to every workload. Compare operational and test input distributions because a changed distribution may favor a different candidate.

Record input size, call count, copied bytes, computation time and whole-request time. Compare error rate and peak memory under the same load. Improvement in the compute stage alone is not sufficient evidence to approve a service migration. Timing only successful requests favors candidates that discard slow or large inputs.

Selection criteria and failure boundaries

Independent scaling and failure isolation come with copying, networking and version-management costs.

Misconceptions to avoid: A function becoming four times faster does not make the request four times faster; include other costs.

Verify it yourself

Calculate the 200ms and 230ms figures for the hypothetical request, and build a table for measuring the same stages in real candidates.

What to judgeMeasuring both sides of a boundary reveals whether computation savings offset transfer costs.

To summarize this chapter

A language boundary slows the request if added serialization, copying and waiting outweigh computation savings.

Official sources for this chapter

The technical facts in the text were reviewed against the following primary sources. The author reconstructed the diagrams and comparisons using these materials.

  1. Python Software Foundation, 「asyncio — Asynchronous I/OReview date 2026-08-28 · Scope Python 3.14 documentation
  2. The Rust Project, 「What Is Ownership?Review date 2026-08-28 · Scope The Rust Programming Language
  3. The Go Authors, 「Effective GoReview date 2026-08-28 · Scope Go official documentation

CHAPTER 7 / 8

Define queue limits and cancellation completion before adding concurrency

Concurrency must be evaluated against downstream capacity and resources reclaimed after cancellation.

Why this concept became necessary

Being able to create many async functions or goroutines does not imply unlimited database connections. Started tasks can consume memory while waiting for connections. Creating more work is not a solution once throughput stops rising and only the queue grows.

Admission control defines when to queue requests and when to reject work that cannot currently be processed. Set queue capacity and maximum waiting time separately. Return a retryable state and useful next steps rather than making users wait silently.

Cancellation has two aspects: the caller stops waiting, and the actual work releases resources. If a downstream call ignores cancellation, connections and workers remain after the UI finishes. Design cancellation propagation and cleanup independently of concurrency syntax.

Python asyncio is a means of coordinating waits, and Go's concurrency tools do not automatically determine job lifecycles either. Maximum concurrent work, time limits, and terminal states come from application requirements. Choose by observing what remains under saturation, not by language name.

Figure 8-8. Define queue limits and cancellation completion before adding concurrency: decision flowThe chain from the problem conditions through the working principle to verification evidence.
Problems and selection criteria

Concurrency must be evaluated against downstream capacity and resources reclaimed after cancellation.

How it works

Admission control communicates downstream limits upstream, while cancellation cleanup removes unnecessary waiting.

Verification evidence

In the 10-connection, 100-request scenario, verify that tasks and connections return to baseline after cancellation.

Follow it through a concrete system

Assume a teaching query API has 10 connections and receives 100 simultaneous requests. If every request performs a similar query, the rest must wait for connections. Compare 100 workers with admission control aligned to 10 connections under the same load. These values illustrate saturation rather than measured performance; verify the actual connection limit in the environment.

Observe queueing time and connections remaining after cancellation, not just completed requests. If departed users' requests keep executing, new users wait behind unnecessary work. Check when canceled tasks return reusable connections. Checking only the cancellation response can mistake still-running background work for successfully terminated work.

If the downstream system has spare capacity and I/O waiting dominates, more concurrency can increase throughput. Still measure the point at which latency and errors start rising. Neither low concurrency nor high concurrency is universally best. With mixed workloads, separately observe short requests waiting behind long ones.

Inject connection delays and user cancellation together and check whether active work returns to baseline. If not, investigate leaks or unfinished jobs. Use the evidence to decide whether admission control and cleanup need fixing before changing languages. Failure to return to baseline after stopping new requests is a recovery problem distinct from temporary overload.

Selection criteria and failure boundaries

Early rejection increases immediate failures for some requests but can prevent queue collapse.

Misconceptions to avoid: Caller cancellation does not imply immediate server-resource reclamation; observe cleanup completion.

Verify it yourself

In the 10-connection, 100-request scenario, verify that tasks and connections return to baseline after cancellation.

What to judgeAdmission control communicates downstream limits upstream, while cancellation cleanup removes unnecessary waiting.

To summarize this chapter

Concurrency must be evaluated against downstream capacity and resources reclaimed after cancellation.

Official sources for this chapter

The technical facts in the text were reviewed against the following primary sources. The author reconstructed the diagrams and comparisons using these materials.

  1. Python Software Foundation, 「asyncio — Asynchronous I/OReview date 2026-08-28 · Scope Python 3.14 documentation
  2. The Go Authors, 「Effective GoReview date 2026-08-28 · Scope Go official documentation

CHAPTER 8 / 8

Separate memory safety from business-input validation

Test ownership guarantees separately from input size, authorization and error handling.

Why this concept became necessary

Rust ownership imposes rules on value use and lifetime. It does not automatically reject an invalid file format or an unauthorized customer request. Even with a memory-safe implementation language, define acceptable business inputs explicitly.

Cross-language boundaries carry lengths, encodings and error representations. A number interpreted as bytes on one side and characters on the other defines incompatible contracts. Agree on empty, truncated and unsupported inputs as well as successful results.

Check resource limits before accepting large inputs. Allocation without a memory error is still unsafe operationally if it exhausts the service. Connect input limits to stages where decompression or intermediate representations expand data, not only to final computation.

Adding an extension module increases deployment combinations. Check that the operating system, processor, and caller and module versions match. Compilation success and successful loading in the actual deployment environment are distinct evidence and should be recorded separately.

Figure 8-9. Separate memory safety from business-input validation: decision flowThe chain from the problem conditions through the working principle to verification evidence.
Problems and selection criteria

Test ownership guarantees separately from input size, authorization and error handling.

How it works

Separating lifetime rules from input semantics reveals boundary errors outside compiler checks.

Verification evidence

Apply returned offsets to mixed-script input and verify byte/character units and error-handling contracts.

Follow it through a concrete system

Assume a teaching document parser receives UTF-8 and returns word positions. Because a Korean character occupies multiple bytes, confusing character indices with byte offsets misaligns highlighting. Define the unit of returned positions in the calling contract first. Without documented offset units, both implementations can claim correctness while returning different answers.

Write the same sentence as input that mixes Korean, English, and emoji, and send it to both implementations. Slice the original text at the returned positions and verify that the same words come out. An integer value type alone cannot catch this semantic difference. Record the returned start and end positions, not just the visible highlights, to reproduce differences at the boundary.

Comparing speed and correctness using only small English files is insufficient. Byte and character positions may coincide there, hiding the defect. Add truncated UTF-8 and oversized inputs to verify that callers do not treat errors as successful results. Verify that invalid-input errors survive as exceptions or status codes in the calling language.

Document units, maximum size, error categories, and whether ownership transfers across the verified boundary. Reuse the same data as regression inputs when changing the caller. Be able to explain the benefit and remaining risk of the narrow compute boundary without rewriting the whole service. When replacing the module, run both the old and new callers against the same input data to check compatibility.

Selection criteria and failure boundaries

Performance gains come with deployment combinations, error conversion and calling-contract maintenance.

Misconceptions to avoid: Rust does not make every input safe; size and semantics require separate validation.

Verify it yourself

Apply returned offsets to mixed-script input and verify byte/character units and error-handling contracts.

What to judgeSeparating lifetime rules from input semantics reveals boundary errors outside compiler checks.

To summarize this chapter

Test ownership guarantees separately from input size, authorization and error handling.

Official sources for this chapter

The technical facts in the text were reviewed against the following primary sources. The author reconstructed the diagrams and comparisons using these materials.

  1. The Rust Project, 「What Is Ownership?Review date 2026-08-28 · Scope The Rust Programming Language
  2. Microsoft, 「Type CompatibilityReview date 2026-08-28 · Scope Latest official documentation

INTERACTIVE LAB 1 / 2

Lab 1 · Choose languages for bottlenecks, not trends

The React product's API mostly waits for the database and LLM, while one PDF parser continuously uses 4 CPU cores. The team is familiar with TypeScript and Python.

Choose the best-supported improvement.

Choose an answer

Correct answer A

A. Keep the API contract and I/O structure, profile the parser, isolate it in a bounded worker or verified Go/Rust component, then measure the end-to-end SLO again.A decision that accounts for conditions, working principles, and failure boundaries together.

B. Immediately rewrite every frontend and API in Rust.It considers only some benefits and omits prerequisites or newly introduced failure boundaries.

C. Adding async to a Python function automatically uses 4 CPU cores.It treats the responsibilities of different layers as one and misses the actual verification points.

D. Replace the database with the top-ranked popular language.It relies on technology names or trends, with no observable evidence from the current requirements.

INTERACTIVE LAB 2 / 2

Lab 2 · Judge compute speed separately from total request time

A hypothetical image request takes 80ms of computation plus 120ms of other work. A separate-language service computes in 20ms but adds 90ms of transfer and reconstruction. Assume identical accuracy and input.

Choose the decision supported by current evidence when the goal is reducing whole-request latency.

Choose an answer

Correct answer D

A. Migrate the whole service immediately because computation is four times faster.Comparing only the compute stage omits the new boundary’s costs, so it does not judge how long the user actually waits.

B. Exclude transfer costs because they are unrelated to the language.Even if not intrinsic to the language, transfer is a real cost of the chosen architecture and belongs in request latency.

C. Rule out a separate service forever because it is slow for every input.One hypothetical input cannot establish results for different compute shares and payload sizes.

D. Compare 200ms with 230ms, hold migration under these conditions and separately measure candidates with different payload sizes or boundaries.Judges the current conditions unfavorable on total cost while leaving other conditions as a task for actual measurement.

KEY TERMS

Key terms in this unit

Measure workload before language
Profiles and benchmarks quantify the share of time and resources that can be optimized.
TypeScript: Web, Agent, and MCP contracts
Static checkers and the JavaScript ecosystem provide fast feedback on end-to-end product changes.
Python: AI, data, and rapid experimentation
A coroutine yields control at I/O wait points, allowing one thread to coordinate many connections.
Go: Gateway · Concurrency · Operational simplicity
The runtime scheduler multiplexes many goroutines onto OS threads, and the goroutines cooperate through channels and context.
Rust: Memory safety and high-cost boundaries
The compiler checks value ownership, lifetimes, and thread-safety traits and rejects invalid memory use.
Measure transfer costs before moving fast computation into another service
Measuring both sides of a boundary reveals whether computation savings offset transfer costs.
Define queue limits and cancellation completion before adding concurrency
Admission control communicates downstream limits upstream, while cancellation cleanup removes unnecessary waiting.
Separate memory safety from business-input validation
Separating lifetime rules from input semantics reveals boundary errors outside compiler checks.

UNIT WORKBOOK

Exercises and worksheets for applying concepts to new situations

Start by checking basic principles, then expand to practical workplace decisions. After submitting an answer, you can see why every option is correct or incorrect, not just the correct answer.

THREE-LEVEL ASSESSMENT

From basic principles to operational decisions

After you submit an answer, you can see not only the correct answer but also why each option is right or wrong.

Basic Question 1

What does Python asyncio directly address?

Choose an answer

Correct answer D

A. Multi-core parallelization of all CPU loops.It considers only some benefits and omits prerequisites or newly introduced failure boundaries.

B. Runtime enforcement of static types.It treats the responsibilities of different layers as one and misses the actual verification points.

C. Automatic database transaction recovery.It relies on technology names or trends, with no observable evidence from the current requirements.

D. Structure concurrency so other coroutines can progress during I/O waits.A decision that accounts for conditions, working principles, and failure boundaries together.

Apply Question 2

What should you check before adding more goroutines in Go?

Choose an answer

Correct answer A

A. Queue and downstream capacity, cancellation, races, and tail latency.A decision that accounts for conditions, working principles, and failure boundaries together.

B. The logo color.It considers only some benefits and omits prerequisites or newly introduced failure boundaries.

C. Rust ownership rules.It treats the responsibilities of different layers as one and misses the actual verification points.

D. Only the frontend bundle size.It relies on technology names or trends, with no observable evidence from the current requirements.

Capstone Question 3

What is the go/no-go evidence for a language rewrite?

Choose an answer

Correct answer B

A. A single successful compilation.It relies on technology names or trends, with no observable evidence from the current requirements.

B. The profiled bottleneck's share, representative benchmarks, operational and team costs, and overall SLO improvement.A decision that accounts for conditions, working principles, and failure boundaries together.

C. Only the star count for each language.It considers only some benefits and omits prerequisites or newly introduced failure boundaries.

D. The fact that AI recommended it.It treats the responsibilities of different layers as one and misses the actual verification points.

PRIMARY SOURCES

Course references

This list collects the sources for each chapter. The text and author-created diagrams were prepared by directly reviewing the originals below.

PERSONAL WORKSHEET

A learning worksheet you adapt to your own environment

Your input remains only on the current browser screen and is not stored or transmitted externally. Use categories and pseudonyms instead of actual sensitive information.

OFFICIAL SOURCES

Verify against official sources

Technical, compatibility, and model information reviewed: August 2026

LEARNING RECORD

Have you reviewed the text, decision activities, and all explanations?

Completion status is stored only in this browser.