[{"content":"Overview A process is an independently executing program instance with its own private address space, while a thread is a lightweight unit of execution that runs inside a process and shares that process\u0026rsquo;s memory with its sibling threads. The distinction matters because it determines how much isolation, communication overhead, and crash-safety you get versus how cheap context switching and data sharing are.\nComparison Diagram Process Thread Process A Code Data Heap Stack Process B Code Data Heap Stack no shared memory (IPC only) single process address space Shared Code / Data / Heap Thread 1 Stack Registers Thread 2 Stack Registers Thread 3 Stack Registers shared heap/code, private stack per thread Comparison Table Aspect Process Thread Memory space Own isolated virtual address space Shares address space with sibling threads in the same process Creation cost Expensive (fork/CreateProcess, new page tables) Cheap (allocate stack + TCB, reuse existing address space) Context switch cost Higher (flush TLB, swap page tables) Lower (same address space, just swap registers/stack pointer) Communication Requires IPC: pipes, sockets, shared memory, message queues Direct via shared variables/heap; needs locks/mutexes for safety Fault isolation A crash typically stays contained to that process A crash (e.g. bad pointer, unhandled exception) can take down the whole process Scheduling unit OS schedules processes (which contain ≥ 1 thread) OS (or runtime) schedules threads independently within a process Concurrency primitives needed Rarely needed within a single process Mutexes, semaphores, atomics to guard shared state Typical use case Running separate, independently-failing programs (browser tabs as processes, microservices) Parallelizing work within one program (web server handling many requests, UI thread + workers) Key Differences A thread lives inside a process and shares its code, heap, and open file handles; a process owns its own private address space. Threads communicate by directly reading/writing shared memory (needing synchronization); processes must use explicit IPC mechanisms. Creating and context-switching a thread is much cheaper than doing the same for a process, since no new address space or page table is involved. A crashing thread can corrupt or kill its entire parent process; a crashing process is generally isolated from other processes by the OS. Multiple threads share one process\u0026rsquo;s resource limits (file descriptors, memory quota); each process gets its own. When to Use Each Process — Choose separate processes when you need strong fault isolation, independent resource limits, or to run untrusted/unrelated code (e.g. sandboxing a plugin, isolating microservices, or letting one crash not affect others).\nThread — Choose threads when you need low-overhead parallelism that shares data tightly within one program, such as handling many concurrent connections or offloading CPU work without duplicating memory.\n","permalink":"https://comparison.metacog.co.kr/posts/2026-08-02-process-vs-thread-isolation-vs-shared-execution/","summary":"\u003ch2 id=\"overview\"\u003eOverview\u003c/h2\u003e\n\u003cp\u003eA process is an independently executing program instance with its own private address space, while a thread is a lightweight unit of execution that runs inside a process and shares that process\u0026rsquo;s memory with its sibling threads. The distinction matters because it determines how much isolation, communication overhead, and crash-safety you get versus how cheap context switching and data sharing are.\u003c/p\u003e\n\u003ch2 id=\"comparison-diagram\"\u003eComparison Diagram\u003c/h2\u003e\n\u003cdiv class=\"compare-diagram\"\u003e\n\u003csvg viewBox=\"0 0 640 360\" xmlns=\"http://www.w3.org/2000/svg\"\u003e\n  \u003ctext x=\"95\" y=\"35\" text-anchor=\"middle\" style=\"fill:var(--primary)\" font-size=\"18\" font-weight=\"bold\"\u003eProcess\u003c/text\u003e\n  \u003ctext x=\"475\" y=\"35\" text-anchor=\"middle\" style=\"fill:var(--primary)\" font-size=\"18\" font-weight=\"bold\"\u003eThread\u003c/text\u003e\n  \u003crect x=\"20\" y=\"55\" width=\"110\" height=\"250\" style=\"fill:var(--compare-a-soft);stroke:var(--compare-a)\" stroke-width=\"1.5\"/\u003e\n  \u003ctext x=\"75\" y=\"72\" text-anchor=\"middle\" style=\"fill:var(--primary)\" font-size=\"11\" font-weight=\"bold\"\u003eProcess A\u003c/text\u003e\n  \u003crect x=\"30\" y=\"80\" width=\"90\" height=\"24\" style=\"fill:none;stroke:var(--border)\" stroke-width=\"1\"/\u003e\n  \u003ctext x=\"75\" y=\"96\" text-anchor=\"middle\" style=\"fill:var(--content)\" font-size=\"9\"\u003eCode\u003c/text\u003e\n  \u003crect x=\"30\" y=\"108\" width=\"90\" height=\"24\" style=\"fill:none;stroke:var(--border)\" stroke-width=\"1\"/\u003e\n  \u003ctext x=\"75\" y=\"124\" text-anchor=\"middle\" style=\"fill:var(--content)\" font-size=\"9\"\u003eData\u003c/text\u003e\n  \u003crect x=\"30\" y=\"136\" width=\"90\" height=\"34\" style=\"fill:none;stroke:var(--border)\" stroke-width=\"1\"/\u003e\n  \u003ctext x=\"75\" y=\"157\" text-anchor=\"middle\" style=\"fill:var(--content)\" font-size=\"9\"\u003eHeap\u003c/text\u003e\n  \u003crect x=\"30\" y=\"174\" width=\"90\" height=\"48\" style=\"fill:none;stroke:var(--border)\" stroke-width=\"1\"/\u003e\n  \u003ctext x=\"75\" y=\"200\" text-anchor=\"middle\" style=\"fill:var(--content)\" font-size=\"9\"\u003eStack\u003c/text\u003e\n  \u003crect x=\"170\" y=\"55\" width=\"110\" height=\"250\" style=\"fill:var(--compare-a-soft);stroke:var(--compare-a)\" stroke-width=\"1.5\"/\u003e\n  \u003ctext x=\"225\" y=\"72\" text-anchor=\"middle\" style=\"fill:var(--primary)\" font-size=\"11\" font-weight=\"bold\"\u003eProcess B\u003c/text\u003e\n  \u003crect x=\"180\" y=\"80\" width=\"90\" height=\"24\" style=\"fill:none;stroke:var(--border)\" stroke-width=\"1\"/\u003e\n  \u003ctext x=\"225\" y=\"96\" text-anchor=\"middle\" style=\"fill:var(--content)\" font-size=\"9\"\u003eCode\u003c/text\u003e\n  \u003crect x=\"180\" y=\"108\" width=\"90\" height=\"24\" style=\"fill:none;stroke:var(--border)\" stroke-width=\"1\"/\u003e\n  \u003ctext x=\"225\" y=\"124\" text-anchor=\"middle\" style=\"fill:var(--content)\" font-size=\"9\"\u003eData\u003c/text\u003e\n  \u003crect x=\"180\" y=\"136\" width=\"90\" height=\"34\" style=\"fill:none;stroke:var(--border)\" stroke-width=\"1\"/\u003e\n  \u003ctext x=\"225\" y=\"157\" text-anchor=\"middle\" style=\"fill:var(--content)\" font-size=\"9\"\u003eHeap\u003c/text\u003e\n  \u003crect x=\"180\" y=\"174\" width=\"90\" height=\"48\" style=\"fill:none;stroke:var(--border)\" stroke-width=\"1\"/\u003e\n  \u003ctext x=\"225\" y=\"200\" text-anchor=\"middle\" style=\"fill:var(--content)\" font-size=\"9\"\u003eStack\u003c/text\u003e\n  \u003cline x1=\"131\" y1=\"165\" x2=\"169\" y2=\"165\" style=\"stroke:var(--secondary)\" stroke-width=\"1.5\" stroke-dasharray=\"4,3\"/\u003e\n  \u003ctext x=\"150\" y=\"245\" text-anchor=\"middle\" style=\"fill:var(--secondary)\" font-size=\"9\"\u003eno shared memory\u003c/text\u003e\n  \u003ctext x=\"150\" y=\"258\" text-anchor=\"middle\" style=\"fill:var(--secondary)\" font-size=\"9\"\u003e(IPC only)\u003c/text\u003e\n  \u003crect x=\"340\" y=\"55\" width=\"270\" height=\"250\" style=\"fill:none;stroke:var(--border)\" stroke-width=\"1.5\"/\u003e\n  \u003ctext x=\"475\" y=\"70\" text-anchor=\"middle\" style=\"fill:var(--secondary)\" font-size=\"9\"\u003esingle process address space\u003c/text\u003e\n  \u003crect x=\"355\" y=\"82\" width=\"240\" height=\"50\" style=\"fill:none;stroke:var(--border)\" stroke-width=\"1.5\"/\u003e\n  \u003ctext x=\"475\" y=\"103\" text-anchor=\"middle\" style=\"fill:var(--content)\" font-size=\"9\"\u003eShared Code / Data / Heap\u003c/text\u003e\n  \u003cline x1=\"390\" y1=\"132\" x2=\"390\" y2=\"160\" style=\"stroke:var(--compare-b)\" stroke-width=\"1.5\"/\u003e\n  \u003cline x1=\"475\" y1=\"132\" x2=\"475\" y2=\"160\" style=\"stroke:var(--compare-b)\" stroke-width=\"1.5\"/\u003e\n  \u003cline x1=\"560\" y1=\"132\" x2=\"560\" y2=\"160\" style=\"stroke:var(--compare-b)\" stroke-width=\"1.5\"/\u003e\n  \u003crect x=\"355\" y=\"160\" width=\"70\" height=\"130\" style=\"fill:var(--compare-b-soft);stroke:var(--compare-b)\" stroke-width=\"1.5\"/\u003e\n  \u003ctext x=\"390\" y=\"176\" text-anchor=\"middle\" style=\"fill:var(--primary)\" font-size=\"9\" font-weight=\"bold\"\u003eThread 1\u003c/text\u003e\n  \u003crect x=\"362\" y=\"184\" width=\"56\" height=\"44\" style=\"fill:none;stroke:var(--border)\" stroke-width=\"1\"/\u003e\n  \u003ctext x=\"390\" y=\"209\" text-anchor=\"middle\" style=\"fill:var(--content)\" font-size=\"8\"\u003eStack\u003c/text\u003e\n  \u003crect x=\"362\" y=\"232\" width=\"56\" height=\"44\" style=\"fill:none;stroke:var(--border)\" stroke-width=\"1\"/\u003e\n  \u003ctext x=\"390\" y=\"257\" text-anchor=\"middle\" style=\"fill:var(--content)\" font-size=\"8\"\u003eRegisters\u003c/text\u003e\n  \u003crect x=\"440\" y=\"160\" width=\"70\" height=\"130\" style=\"fill:var(--compare-b-soft);stroke:var(--compare-b)\" stroke-width=\"1.5\"/\u003e\n  \u003ctext x=\"475\" y=\"176\" text-anchor=\"middle\" style=\"fill:var(--primary)\" font-size=\"9\" font-weight=\"bold\"\u003eThread 2\u003c/text\u003e\n  \u003crect x=\"447\" y=\"184\" width=\"56\" height=\"44\" style=\"fill:none;stroke:var(--border)\" stroke-width=\"1\"/\u003e\n  \u003ctext x=\"475\" y=\"209\" text-anchor=\"middle\" style=\"fill:var(--content)\" font-size=\"8\"\u003eStack\u003c/text\u003e\n  \u003crect x=\"447\" y=\"232\" width=\"56\" height=\"44\" style=\"fill:none;stroke:var(--border)\" stroke-width=\"1\"/\u003e\n  \u003ctext x=\"475\" y=\"257\" text-anchor=\"middle\" style=\"fill:var(--content)\" font-size=\"8\"\u003eRegisters\u003c/text\u003e\n  \u003crect x=\"525\" y=\"160\" width=\"70\" height=\"130\" style=\"fill:var(--compare-b-soft);stroke:var(--compare-b)\" stroke-width=\"1.5\"/\u003e\n  \u003ctext x=\"560\" y=\"176\" text-anchor=\"middle\" style=\"fill:var(--primary)\" font-size=\"9\" font-weight=\"bold\"\u003eThread 3\u003c/text\u003e\n  \u003crect x=\"532\" y=\"184\" width=\"56\" height=\"44\" style=\"fill:none;stroke:var(--border)\" stroke-width=\"1\"/\u003e\n  \u003ctext x=\"560\" y=\"209\" text-anchor=\"middle\" style=\"fill:var(--content)\" font-size=\"8\"\u003eStack\u003c/text\u003e\n  \u003crect x=\"532\" y=\"232\" width=\"56\" height=\"44\" style=\"fill:none;stroke:var(--border)\" stroke-width=\"1\"/\u003e\n  \u003ctext x=\"560\" y=\"257\" text-anchor=\"middle\" style=\"fill:var(--content)\" font-size=\"8\"\u003eRegisters\u003c/text\u003e\n\u003cp\u003e\u003ctext x=\"475\" y=\"312\" text-anchor=\"middle\" style=\"fill:var(--secondary)\" font-size=\"9\"\u003eshared heap/code, private stack per thread\u003c/text\u003e\n\u003c/svg\u003e\u003c/p\u003e","title":"Process vs Thread: Isolation vs Shared Execution"},{"content":"Overview Authentication (AuthN) confirms who a user or system claims to be, typically through credentials like passwords, biometrics, or tokens. Authorization (AuthZ) determines what an already-authenticated identity is permitted to do or access. The two are sequential and often conflated, but security bugs frequently trace back to confusing one for the other — e.g., checking that a user is logged in without checking they\u0026rsquo;re allowed to see a specific resource.\nComparison Diagram ClientcredentialsAUTHENTICATION\"Who are you?\"Verifies identity401 Unauthorizedlogin, MFA, SSOidentity/tokenAUTHORIZATION\"What can you do?\"Grants/denies access403 ForbiddenRBAC, scopes, ACLsdecisionResource Comparison Table Aspect Authentication Authorization Question answered Who are you? What are you allowed to do? Occurs when At login, before any access is granted After authentication, on every protected action or resource Input Credentials — password, biometric, hardware key, OTP Verified identity plus roles, scopes, or attributes Output A confirmed identity (session, JWT, ID token) An allow/deny decision Failure response 401 Unauthorized 403 Forbidden Common mechanisms Passwords, MFA, WebAuthn/passkeys, SSO RBAC, ABAC, ACLs, OAuth 2.0 scopes Relevant standards OpenID Connect, SAML, WebAuthn OAuth 2.0, XACML, policy engines (e.g. OPA) Enforced by Identity provider or login boundary Application logic, API gateway, or policy engine Key Differences Authorization always presumes authentication already happened — you can\u0026rsquo;t check permissions for an identity you haven\u0026rsquo;t verified. 401 vs 403 encode the distinction directly: 401 means \u0026lsquo;we don\u0026rsquo;t know who you are,\u0026rsquo; 403 means \u0026lsquo;we know, but you can\u0026rsquo;t do that.\u0026rsquo; Authentication is typically a one-time event per session; authorization is re-evaluated on every sensitive request or resource access. OAuth 2.0 is an authorization framework, not an authentication protocol — OpenID Connect layers identity verification on top of it, a distinction frequently misunderstood in practice. When to Use Each Authentication — Focus on authentication when the problem is proving identity — building or hardening login flows, adding MFA, or integrating SSO/OpenID Connect.\nAuthorization — Focus on authorization when the problem is controlling access after identity is known — designing RBAC/ABAC models, API scopes, or per-resource permission checks.\n","permalink":"https://comparison.metacog.co.kr/posts/2026-08-02-authentication-vs-authorization-verifying-identity-vs-granti/","summary":"\u003ch2 id=\"overview\"\u003eOverview\u003c/h2\u003e\n\u003cp\u003eAuthentication (AuthN) confirms who a user or system claims to be, typically through credentials like passwords, biometrics, or tokens. Authorization (AuthZ) determines what an already-authenticated identity is permitted to do or access. The two are sequential and often conflated, but security bugs frequently trace back to confusing one for the other — e.g., checking that a user is logged in without checking they\u0026rsquo;re allowed to see a specific resource.\u003c/p\u003e","title":"Authentication vs. Authorization: Verifying Identity vs. Granting Access"},{"content":"Overview REST and GraphQL are both HTTP-based API paradigms that differ fundamentally in how clients request data. REST exposes multiple URLs with server-defined response shapes; GraphQL exposes a single endpoint where the client\u0026rsquo;s query body dictates exactly which fields and relationships to return. The distinction drives decisions around over-fetching, N+1 latency, HTTP cacheability, and schema contracts.\nComparison Diagram RESTmultiple endpoints, fixed shapeClientGET /usersGET /postsGET /comments3 requestsEach response = full object:{ id, name, email, avatarUrl, createdAt, role, prefs }only name+email needed → over-fetchRelated data → N+1 round-tripsBreaking change → new URL, e.g. /v2/GET · cacheable · status codesGraphQLone endpoint, client-declared shapeClientPOST /graphql1 requestquery (client-authored)query { user(id: 1) { name email } posts { title }}SDL schema (server)type User { name: String! email: String posts: [Post]}Response: exactly what was declared{ user: { name, email }, posts: [{ title }] }Schema evolves via @deprecated, no versioningPOST · typed schema · introspectable Comparison Table Aspect REST GraphQL Endpoints One URL per resource type — GET /users, POST /orders, etc. Single URL (POST /graphql); resource selection is in the query body Response shape Fixed by the server; client receives all fields the endpoint defines Declared by the client per query; only the requested fields are returned Over/under-fetching Chronic: server returns full objects; client discards unused fields or must make extra requests for missing ones Eliminated by design: resolvers return only fields the query specifies HTTP caching Native: GET responses cache at CDN and browser level by URL + headers Non-trivial: queries are POST bodies; requires persisted queries or APQ for cache-key stability Type system Optional — enforced only if you add OpenAPI/JSON Schema; not validated at runtime by default Mandatory SDL schema; all queries are parsed and validated against it before execution Versioning Breaking changes typically require new URL paths (/v1/, /v2/) or custom Accept headers Additive schema evolution with @deprecated directives; a single endpoint surface stays stable Error handling HTTP status codes carry semantic meaning: 200, 404, 422, 500, etc. Always 200 OK; errors surface in an errors[] array alongside any partial data Introspection / discoverability Requires an external spec (OpenAPI/Swagger); not built into the protocol Built-in: query __schema or __type to get the full type graph at runtime Key Differences REST has one endpoint per resource; GraphQL has one endpoint for the entire API, and the query body — not the URL — determines what data comes back. REST responses return all server-defined fields for a resource (over-fetch), and fetching related data requires additional round-trips (N+1 problem). A single GraphQL query can traverse multiple types and return exactly the fields requested. REST uses standard HTTP verbs and status codes, making GET-based CDN and browser caching trivially available. GraphQL queries travel as POST bodies, breaking HTTP cache semantics by default and requiring explicit workarounds. GraphQL\u0026rsquo;s SDL provides a mandatory, introspectable type contract enforced at parse time. REST type contracts are optional add-ons (OpenAPI); the server can return anything without violating the protocol. REST breaking changes typically force a new URL version (/v2/); GraphQL prefers additive schema evolution with @deprecated, keeping a single endpoint surface over the API\u0026rsquo;s lifetime. When to Use Each REST — Use REST when HTTP semantics matter: public APIs where CDN caching, stateless GET-based reads, and broad ecosystem compatibility (browsers, curl, API gateways) are first-class requirements. Also the natural default when each resource type is consumed independently and maps cleanly to standard CRUD verbs.\nGraphQL — Use GraphQL when clients — especially mobile apps or SPAs — need to fetch heterogeneous, joined data in a single round-trip to minimize latency and bandwidth. It pays off most when multiple clients (iOS, Android, web) have divergent field requirements that would otherwise force over-fetching or proliferating endpoint variants.\n","permalink":"https://comparison.metacog.co.kr/posts/2026-08-02-rest-vs-graphql-api-query-model/","summary":"\u003ch2 id=\"overview\"\u003eOverview\u003c/h2\u003e\n\u003cp\u003eREST and GraphQL are both HTTP-based API paradigms that differ fundamentally in how clients request data. REST exposes multiple URLs with server-defined response shapes; GraphQL exposes a single endpoint where the client\u0026rsquo;s query body dictates exactly which fields and relationships to return. The distinction drives decisions around over-fetching, N+1 latency, HTTP cacheability, and schema contracts.\u003c/p\u003e\n\u003ch2 id=\"comparison-diagram\"\u003eComparison Diagram\u003c/h2\u003e\n\u003cdiv class=\"compare-diagram\"\u003e\n\u003csvg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 640 360\"\u003e\u003cline x1=\"320\" y1=\"8\" x2=\"320\" y2=\"352\" style=\"stroke:var(--border)\" stroke-width=\"1\"/\u003e\u003ctext x=\"160\" y=\"26\" text-anchor=\"middle\" style=\"fill:var(--primary)\" font-family=\"ui-monospace,monospace\" font-size=\"17\" font-weight=\"700\"\u003eREST\u003c/text\u003e\u003ctext x=\"160\" y=\"43\" text-anchor=\"middle\" style=\"fill:var(--secondary)\" font-family=\"ui-monospace,monospace\" font-size=\"10\"\u003emultiple endpoints, fixed shape\u003c/text\u003e\u003crect x=\"20\" y=\"60\" width=\"64\" height=\"30\" rx=\"4\" style=\"fill:var(--compare-a-soft);stroke:var(--compare-a)\" stroke-width=\"1.5\"/\u003e\u003ctext x=\"52\" y=\"80\" text-anchor=\"middle\" style=\"fill:var(--content)\" font-family=\"ui-monospace,monospace\" font-size=\"11\"\u003eClient\u003c/text\u003e\u003crect x=\"130\" y=\"52\" width=\"150\" height=\"24\" rx=\"3\" style=\"fill:var(--compare-a-soft);stroke:var(--compare-a)\" stroke-width=\"1\"/\u003e\u003ctext x=\"205\" y=\"68\" text-anchor=\"middle\" style=\"fill:var(--content)\" font-family=\"ui-monospace,monospace\" font-size=\"10\"\u003eGET /users\u003c/text\u003e\u003crect x=\"130\" y=\"82\" width=\"150\" height=\"24\" rx=\"3\" style=\"fill:var(--compare-a-soft);stroke:var(--compare-a)\" stroke-width=\"1\"/\u003e\u003ctext x=\"205\" y=\"98\" text-anchor=\"middle\" style=\"fill:var(--content)\" font-family=\"ui-monospace,monospace\" font-size=\"10\"\u003eGET /posts\u003c/text\u003e\u003crect x=\"130\" y=\"112\" width=\"150\" height=\"24\" rx=\"3\" style=\"fill:var(--compare-a-soft);stroke:var(--compare-a)\" stroke-width=\"1\"/\u003e\u003ctext x=\"205\" y=\"128\" text-anchor=\"middle\" style=\"fill:var(--content)\" font-family=\"ui-monospace,monospace\" font-size=\"10\"\u003eGET /comments\u003c/text\u003e\u003cline x1=\"84\" y1=\"70\" x2=\"128\" y2=\"64\" style=\"stroke:var(--compare-a)\" stroke-width=\"1.5\"/\u003e\u003cline x1=\"84\" y1=\"74\" x2=\"128\" y2=\"94\" style=\"stroke:var(--compare-a)\" stroke-width=\"1.5\"/\u003e\u003cline x1=\"84\" y1=\"78\" x2=\"128\" y2=\"124\" style=\"stroke:var(--compare-a)\" stroke-width=\"1.5\"/\u003e\u003ctext x=\"106\" y=\"58\" text-anchor=\"middle\" style=\"fill:var(--secondary)\" font-family=\"ui-monospace,monospace\" font-size=\"9\"\u003e3 requests\u003c/text\u003e\u003crect x=\"20\" y=\"150\" width=\"280\" height=\"70\" rx=\"4\" style=\"fill:none;stroke:var(--border)\" stroke-width=\"1\" stroke-dasharray=\"4,3\"/\u003e\u003ctext x=\"28\" y=\"166\" style=\"fill:var(--secondary)\" font-family=\"ui-monospace,monospace\" font-size=\"9\"\u003eEach response = full object:\u003c/text\u003e\u003ctext x=\"28\" y=\"182\" style=\"fill:var(--content)\" font-family=\"ui-monospace,monospace\" font-size=\"9\"\u003e{ id, name, email, avatarUrl,\u003c/text\u003e\u003ctext x=\"28\" y=\"196\" style=\"fill:var(--content)\" font-family=\"ui-monospace,monospace\" font-size=\"9\"\u003e  createdAt, role, prefs }\u003c/text\u003e\u003ctext x=\"28\" y=\"212\" style=\"fill:var(--compare-a)\" font-family=\"ui-monospace,monospace\" font-size=\"9\" font-weight=\"600\"\u003eonly name+email needed → over-fetch\u003c/text\u003e\u003crect x=\"20\" y=\"232\" width=\"280\" height=\"26\" rx=\"3\" style=\"fill:var(--compare-a-soft);stroke:var(--compare-a)\" stroke-width=\"1\"/\u003e\u003ctext x=\"160\" y=\"250\" text-anchor=\"middle\" style=\"fill:var(--content)\" font-family=\"ui-monospace,monospace\" font-size=\"10\"\u003eRelated data → N+1 round-trips\u003c/text\u003e\u003crect x=\"20\" y=\"266\" width=\"280\" height=\"26\" rx=\"3\" style=\"fill:none;stroke:var(--border)\" stroke-width=\"1\"/\u003e\u003ctext x=\"160\" y=\"284\" text-anchor=\"middle\" style=\"fill:var(--secondary)\" font-family=\"ui-monospace,monospace\" font-size=\"9\"\u003eBreaking change → new URL, e.g. /v2/\u003c/text\u003e\u003ctext x=\"160\" y=\"326\" text-anchor=\"middle\" style=\"fill:var(--compare-a)\" font-family=\"ui-monospace,monospace\" font-size=\"10\" font-weight=\"600\"\u003eGET · cacheable · status codes\u003c/text\u003e\u003ctext x=\"480\" y=\"26\" text-anchor=\"middle\" style=\"fill:var(--primary)\" font-family=\"ui-monospace,monospace\" font-size=\"17\" font-weight=\"700\"\u003eGraphQL\u003c/text\u003e\u003ctext x=\"480\" y=\"43\" text-anchor=\"middle\" style=\"fill:var(--secondary)\" font-family=\"ui-monospace,monospace\" font-size=\"10\"\u003eone endpoint, client-declared shape\u003c/text\u003e\u003crect x=\"340\" y=\"60\" width=\"64\" height=\"30\" rx=\"4\" style=\"fill:var(--compare-b-soft);stroke:var(--compare-b)\" stroke-width=\"1.5\"/\u003e\u003ctext x=\"372\" y=\"80\" text-anchor=\"middle\" style=\"fill:var(--content)\" font-family=\"ui-monospace,monospace\" font-size=\"11\"\u003eClient\u003c/text\u003e\u003crect x=\"460\" y=\"64\" width=\"150\" height=\"24\" rx=\"3\" style=\"fill:var(--compare-b-soft);stroke:var(--compare-b)\" stroke-width=\"1.5\"/\u003e\u003ctext x=\"535\" y=\"80\" text-anchor=\"middle\" style=\"fill:var(--content)\" font-family=\"ui-monospace,monospace\" font-size=\"10\"\u003ePOST /graphql\u003c/text\u003e\u003cline x1=\"404\" y1=\"75\" x2=\"458\" y2=\"75\" style=\"stroke:var(--compare-b)\" stroke-width=\"1.5\"/\u003e\u003ctext x=\"431\" y=\"68\" text-anchor=\"middle\" style=\"fill:var(--secondary)\" font-family=\"ui-monospace,monospace\" font-size=\"9\"\u003e1 request\u003c/text\u003e\u003crect x=\"340\" y=\"100\" width=\"140\" height=\"110\" rx=\"4\" style=\"fill:none;stroke:var(--border)\" stroke-width=\"1\"/\u003e\u003ctext x=\"410\" y=\"115\" text-anchor=\"middle\" style=\"fill:var(--secondary)\" font-family=\"ui-monospace,monospace\" font-size=\"9\"\u003equery (client-authored)\u003c/text\u003e\u003ctext x=\"348\" y=\"133\" style=\"fill:var(--content)\" font-family=\"ui-monospace,monospace\" font-size=\"9\"\u003equery {\u003c/text\u003e\u003ctext x=\"348\" y=\"147\" style=\"fill:var(--content)\" font-family=\"ui-monospace,monospace\" font-size=\"9\"\u003e  user(id: 1) {\u003c/text\u003e\u003ctext x=\"348\" y=\"161\" style=\"fill:var(--compare-b)\" font-family=\"ui-monospace,monospace\" font-size=\"9\" font-weight=\"600\"\u003e    name email\u003c/text\u003e\u003ctext x=\"348\" y=\"175\" style=\"fill:var(--content)\" font-family=\"ui-monospace,monospace\" font-size=\"9\"\u003e  }\u003c/text\u003e\u003ctext x=\"348\" y=\"189\" style=\"fill:var(--content)\" font-family=\"ui-monospace,monospace\" font-size=\"9\"\u003e  posts { title }\u003c/text\u003e\u003ctext x=\"348\" y=\"203\" style=\"fill:var(--content)\" font-family=\"ui-monospace,monospace\" font-size=\"9\"\u003e}\u003c/text\u003e\u003crect x=\"490\" y=\"100\" width=\"126\" height=\"110\" rx=\"4\" style=\"fill:none;stroke:var(--border)\" stroke-width=\"1\"/\u003e\u003ctext x=\"553\" y=\"115\" text-anchor=\"middle\" style=\"fill:var(--secondary)\" font-family=\"ui-monospace,monospace\" font-size=\"9\"\u003eSDL schema (server)\u003c/text\u003e\u003ctext x=\"498\" y=\"133\" style=\"fill:var(--content)\" font-family=\"ui-monospace,monospace\" font-size=\"9\"\u003etype User {\u003c/text\u003e\u003ctext x=\"498\" y=\"147\" style=\"fill:var(--content)\" font-family=\"ui-monospace,monospace\" font-size=\"9\"\u003e  name: String!\u003c/text\u003e\u003ctext x=\"498\" y=\"161\" style=\"fill:var(--content)\" font-family=\"ui-monospace,monospace\" font-size=\"9\"\u003e  email: String\u003c/text\u003e\u003ctext x=\"498\" y=\"175\" style=\"fill:var(--content)\" font-family=\"ui-monospace,monospace\" font-size=\"9\"\u003e  posts: [Post]\u003c/text\u003e\u003ctext x=\"498\" y=\"189\" style=\"fill:var(--content)\" font-family=\"ui-monospace,monospace\" font-size=\"9\"\u003e}\u003c/text\u003e\u003crect x=\"340\" y=\"220\" width=\"276\" height=\"40\" rx=\"4\" style=\"fill:var(--compare-b-soft);stroke:var(--compare-b)\" stroke-width=\"1\"/\u003e\u003ctext x=\"478\" y=\"235\" text-anchor=\"middle\" style=\"fill:var(--content)\" font-family=\"ui-monospace,monospace\" font-size=\"9\"\u003eResponse: exactly what was declared\u003c/text\u003e\u003ctext x=\"348\" y=\"252\" style=\"fill:var(--content)\" font-family=\"ui-monospace,monospace\" font-size=\"9\"\u003e{ user: { name, email }, posts: [{ title }] }\u003c/text\u003e\u003crect x=\"340\" y=\"266\" width=\"276\" height=\"26\" rx=\"3\" style=\"fill:none;stroke:var(--border)\" stroke-width=\"1\"/\u003e\u003ctext x=\"478\" y=\"284\" text-anchor=\"middle\" style=\"fill:var(--secondary)\" font-family=\"ui-monospace,monospace\" font-size=\"9\"\u003eSchema evolves via @deprecated, no versioning\u003c/text\u003e\u003ctext x=\"478\" y=\"326\" text-anchor=\"middle\" style=\"fill:var(--compare-b)\" font-family=\"ui-monospace,monospace\" font-size=\"10\" font-weight=\"600\"\u003ePOST · typed schema · introspectable\u003c/text\u003e\u003c/svg\u003e\n\u003c/div\u003e\n\u003ch2 id=\"comparison-table\"\u003eComparison Table\u003c/h2\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003eAspect\u003c/th\u003e\n          \u003cth\u003eREST\u003c/th\u003e\n          \u003cth\u003eGraphQL\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eEndpoints\u003c/td\u003e\n          \u003ctd\u003eOne URL per resource type — \u003ccode\u003eGET /users\u003c/code\u003e, \u003ccode\u003ePOST /orders\u003c/code\u003e, etc.\u003c/td\u003e\n          \u003ctd\u003eSingle URL (\u003ccode\u003ePOST /graphql\u003c/code\u003e); resource selection is in the query body\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eResponse shape\u003c/td\u003e\n          \u003ctd\u003eFixed by the server; client receives all fields the endpoint defines\u003c/td\u003e\n          \u003ctd\u003eDeclared by the client per query; only the requested fields are returned\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eOver/under-fetching\u003c/td\u003e\n          \u003ctd\u003eChronic: server returns full objects; client discards unused fields or must make extra requests for missing ones\u003c/td\u003e\n          \u003ctd\u003eEliminated by design: resolvers return only fields the query specifies\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eHTTP caching\u003c/td\u003e\n          \u003ctd\u003eNative: \u003ccode\u003eGET\u003c/code\u003e responses cache at CDN and browser level by URL + headers\u003c/td\u003e\n          \u003ctd\u003eNon-trivial: queries are \u003ccode\u003ePOST\u003c/code\u003e bodies; requires persisted queries or APQ for cache-key stability\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eType system\u003c/td\u003e\n          \u003ctd\u003eOptional — enforced only if you add OpenAPI/JSON Schema; not validated at runtime by default\u003c/td\u003e\n          \u003ctd\u003eMandatory SDL schema; all queries are parsed and validated against it before execution\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eVersioning\u003c/td\u003e\n          \u003ctd\u003eBreaking changes typically require new URL paths (\u003ccode\u003e/v1/\u003c/code\u003e, \u003ccode\u003e/v2/\u003c/code\u003e) or custom \u003ccode\u003eAccept\u003c/code\u003e headers\u003c/td\u003e\n          \u003ctd\u003eAdditive schema evolution with \u003ccode\u003e@deprecated\u003c/code\u003e directives; a single endpoint surface stays stable\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eError handling\u003c/td\u003e\n          \u003ctd\u003eHTTP status codes carry semantic meaning: 200, 404, 422, 500, etc.\u003c/td\u003e\n          \u003ctd\u003eAlways \u003ccode\u003e200 OK\u003c/code\u003e; errors surface in an \u003ccode\u003eerrors[]\u003c/code\u003e array alongside any partial data\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eIntrospection / discoverability\u003c/td\u003e\n          \u003ctd\u003eRequires an external spec (OpenAPI/Swagger); not built into the protocol\u003c/td\u003e\n          \u003ctd\u003eBuilt-in: query \u003ccode\u003e__schema\u003c/code\u003e or \u003ccode\u003e__type\u003c/code\u003e to get the full type graph at runtime\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch2 id=\"key-differences\"\u003eKey Differences\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eREST has one endpoint per resource; GraphQL has one endpoint for the entire API, and the query body — not the URL — determines what data comes back.\u003c/li\u003e\n\u003cli\u003eREST responses return all server-defined fields for a resource (over-fetch), and fetching related data requires additional round-trips (N+1 problem). A single GraphQL query can traverse multiple types and return exactly the fields requested.\u003c/li\u003e\n\u003cli\u003eREST uses standard HTTP verbs and status codes, making GET-based CDN and browser caching trivially available. GraphQL queries travel as POST bodies, breaking HTTP cache semantics by default and requiring explicit workarounds.\u003c/li\u003e\n\u003cli\u003eGraphQL\u0026rsquo;s SDL provides a mandatory, introspectable type contract enforced at parse time. REST type contracts are optional add-ons (OpenAPI); the server can return anything without violating the protocol.\u003c/li\u003e\n\u003cli\u003eREST breaking changes typically force a new URL version (\u003ccode\u003e/v2/\u003c/code\u003e); GraphQL prefers additive schema evolution with \u003ccode\u003e@deprecated\u003c/code\u003e, keeping a single endpoint surface over the API\u0026rsquo;s lifetime.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"when-to-use-each\"\u003eWhen to Use Each\u003c/h2\u003e\n\u003cp\u003e\u003cstrong\u003eREST\u003c/strong\u003e — Use REST when HTTP semantics matter: public APIs where CDN caching, stateless \u003ccode\u003eGET\u003c/code\u003e-based reads, and broad ecosystem compatibility (browsers, curl, API gateways) are first-class requirements. Also the natural default when each resource type is consumed independently and maps cleanly to standard CRUD verbs.\u003c/p\u003e","title":"REST vs GraphQL: API Query Model"},{"content":"Overview The stack and heap are two distinct memory regions used for different allocation strategies at runtime. The stack manages function call frames automatically via a single pointer increment/decrement, while the heap handles dynamic allocations with flexible lifetimes through an allocator. The distinction directly affects allocation speed, data lifetime, size constraints, and thread safety — core considerations in systems, embedded, and performance-sensitive programming.\nComparison Diagram STACKgrows downward, LIFOhighlowframe: main()frame: compute(n)frame: factorial(3)SPunusedauto-managed · O(1) · fast~1-8 MB per threadHEAPunordered, explicit lifetimeObjectVec\u0026lt;T\u0026gt;freeHashMapBoxfreeString dataArcmanual/GC · flexible · fragmentslimited by OS / RAM Comparison Table Aspect Stack Heap Allocation mechanism Pointer decrement — O(1), no bookkeeping Allocator call (malloc/new) — higher constant, free-list bookkeeping Deallocation Automatic on scope/frame exit Explicit (free/delete) or garbage collector Data lifetime Bound to the declaring scope or call frame Arbitrary; can outlive any function call Size constraint Fixed at thread creation (typically 1–8 MB) Limited only by available virtual memory / RAM Size known at compile time Required — compiler must know the type\u0026rsquo;s layout Not required — length/capacity decided at runtime Fragmentation None — LIFO order keeps allocation contiguous Yes — internal and external fragmentation accumulate over time Thread ownership Each thread has its own stack; no synchronization needed Shared across threads; allocator must serialize internally Failure mode Stack overflow → immediate crash (SIGSEGV/signal) OOM → null / exception / OOM-killer; potentially recoverable Key Differences Stack allocation is a single SP register decrement; heap allocation invokes an allocator with metadata updates, free-list traversal, and possible OS syscalls. Stack lifetime is strictly scoped to the function frame — data cannot be returned by pointer from the stack safely; heap memory can be returned, stored globally, or transferred across threads. Each thread has its own stack and needs no locking; the heap is process-wide and requires allocator-level synchronization on every alloc/free. Stack size is fixed and small (set by the OS or linker script); heap can grow dynamically, making it the only viable region for large buffers or runtime-sized collections. Heap fragmentation is a real operational concern in long-lived or allocation-heavy processes; the stack never fragments because it always grows and shrinks from one end in LIFO order. When to Use Each Stack — Prefer the stack for local variables, function arguments, and fixed-size value types whose lifetime is bounded by the enclosing scope — it is faster, deterministic, and eliminates entire classes of memory bugs.\nHeap — Use the heap when data must outlive its creating scope, when the allocation size is unknown at compile time, or when allocating large buffers that would overflow a typical thread stack; it is also required for shared ownership across threads.\n","permalink":"https://comparison.metacog.co.kr/posts/2026-08-02-stack-vs-heap-memory-allocation-models/","summary":"\u003ch2 id=\"overview\"\u003eOverview\u003c/h2\u003e\n\u003cp\u003eThe stack and heap are two distinct memory regions used for different allocation strategies at runtime. The stack manages function call frames automatically via a single pointer increment/decrement, while the heap handles dynamic allocations with flexible lifetimes through an allocator. The distinction directly affects allocation speed, data lifetime, size constraints, and thread safety — core considerations in systems, embedded, and performance-sensitive programming.\u003c/p\u003e\n\u003ch2 id=\"comparison-diagram\"\u003eComparison Diagram\u003c/h2\u003e\n\u003cdiv class=\"compare-diagram\"\u003e\n\u003csvg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 640 360\"\u003e\u003cline x1=\"320\" y1=\"8\" x2=\"320\" y2=\"352\" style=\"stroke:var(--border)\" stroke-width=\"1\"/\u003e\u003ctext x=\"160\" y=\"28\" text-anchor=\"middle\" style=\"fill:var(--primary)\" font-family=\"ui-monospace,Menlo,monospace\" font-size=\"17\" font-weight=\"700\"\u003eSTACK\u003c/text\u003e\u003ctext x=\"160\" y=\"46\" text-anchor=\"middle\" style=\"fill:var(--secondary)\" font-family=\"ui-monospace,Menlo,monospace\" font-size=\"10\"\u003egrows downward, LIFO\u003c/text\u003e\u003cline x1=\"52\" y1=\"60\" x2=\"52\" y2=\"300\" style=\"stroke:var(--compare-a)\" stroke-width=\"1.5\"/\u003e\u003ctext x=\"52\" y=\"56\" text-anchor=\"middle\" style=\"fill:var(--secondary)\" font-family=\"ui-monospace,monospace\" font-size=\"9\"\u003ehigh\u003c/text\u003e\u003ctext x=\"52\" y=\"314\" text-anchor=\"middle\" style=\"fill:var(--secondary)\" font-family=\"ui-monospace,monospace\" font-size=\"9\"\u003elow\u003c/text\u003e\u003crect x=\"76\" y=\"252\" width=\"210\" height=\"38\" rx=\"4\" style=\"fill:var(--compare-a-soft);stroke:var(--compare-a)\" stroke-width=\"1.5\"/\u003e\u003ctext x=\"181\" y=\"276\" text-anchor=\"middle\" style=\"fill:var(--content)\" font-family=\"ui-monospace,monospace\" font-size=\"12\"\u003eframe: main()\u003c/text\u003e\u003crect x=\"76\" y=\"209\" width=\"210\" height=\"38\" rx=\"4\" style=\"fill:var(--compare-a-soft);stroke:var(--compare-a)\" stroke-width=\"1.5\"/\u003e\u003ctext x=\"181\" y=\"233\" text-anchor=\"middle\" style=\"fill:var(--content)\" font-family=\"ui-monospace,monospace\" font-size=\"12\"\u003eframe: compute(n)\u003c/text\u003e\u003crect x=\"76\" y=\"166\" width=\"210\" height=\"38\" rx=\"4\" style=\"fill:var(--compare-a-soft);stroke:var(--compare-a)\" stroke-width=\"2\"/\u003e\u003ctext x=\"181\" y=\"190\" text-anchor=\"middle\" style=\"fill:var(--content)\" font-family=\"ui-monospace,monospace\" font-size=\"12\"\u003eframe: factorial(3)\u003c/text\u003e\u003cpolygon points=\"290,166 302,160 302,172\" style=\"fill:var(--compare-a)\"/\u003e\u003ctext x=\"306\" y=\"172\" style=\"fill:var(--compare-a)\" font-family=\"ui-monospace,monospace\" font-size=\"10\" font-weight=\"600\"\u003eSP\u003c/text\u003e\u003crect x=\"76\" y=\"88\" width=\"210\" height=\"70\" rx=\"4\" style=\"fill:none;stroke:var(--border)\" stroke-width=\"1\" stroke-dasharray=\"4,3\"/\u003e\u003ctext x=\"181\" y=\"127\" text-anchor=\"middle\" style=\"fill:var(--secondary)\" font-family=\"ui-monospace,monospace\" font-size=\"11\"\u003eunused\u003c/text\u003e\u003ctext x=\"181\" y=\"326\" text-anchor=\"middle\" style=\"fill:var(--compare-a)\" font-family=\"ui-monospace,monospace\" font-size=\"10\" font-weight=\"600\"\u003eauto-managed · O(1) · fast\u003c/text\u003e\u003ctext x=\"181\" y=\"341\" text-anchor=\"middle\" style=\"fill:var(--secondary)\" font-family=\"ui-monospace,monospace\" font-size=\"9\"\u003e~1-8 MB per thread\u003c/text\u003e\u003ctext x=\"480\" y=\"28\" text-anchor=\"middle\" style=\"fill:var(--primary)\" font-family=\"ui-monospace,monospace\" font-size=\"17\" font-weight=\"700\"\u003eHEAP\u003c/text\u003e\u003ctext x=\"480\" y=\"46\" text-anchor=\"middle\" style=\"fill:var(--secondary)\" font-family=\"ui-monospace,monospace\" font-size=\"10\"\u003eunordered, explicit lifetime\u003c/text\u003e\u003crect x=\"356\" y=\"60\" width=\"248\" height=\"240\" rx=\"6\" style=\"fill:none;stroke:var(--border)\" stroke-width=\"1\" stroke-dasharray=\"5,3\"/\u003e\u003crect x=\"372\" y=\"76\" width=\"90\" height=\"42\" rx=\"4\" style=\"fill:var(--compare-b-soft);stroke:var(--compare-b)\" stroke-width=\"1.5\"/\u003e\u003ctext x=\"417\" y=\"101\" text-anchor=\"middle\" style=\"fill:var(--content)\" font-family=\"ui-monospace,monospace\" font-size=\"11\"\u003eObject\u003c/text\u003e\u003crect x=\"472\" y=\"76\" width=\"80\" height=\"34\" rx=\"4\" style=\"fill:var(--compare-b-soft);stroke:var(--compare-b)\" stroke-width=\"1.5\"/\u003e\u003ctext x=\"512\" y=\"97\" text-anchor=\"middle\" style=\"fill:var(--content)\" font-family=\"ui-monospace,monospace\" font-size=\"11\"\u003eVec\u0026lt;T\u0026gt;\u003c/text\u003e\u003crect x=\"372\" y=\"128\" width=\"60\" height=\"30\" rx=\"3\" style=\"fill:none;stroke:var(--border)\" stroke-width=\"1\" stroke-dasharray=\"3,2\"/\u003e\u003ctext x=\"402\" y=\"147\" text-anchor=\"middle\" style=\"fill:var(--secondary)\" font-family=\"ui-monospace,monospace\" font-size=\"9\"\u003efree\u003c/text\u003e\u003crect x=\"442\" y=\"120\" width=\"110\" height=\"50\" rx=\"4\" style=\"fill:var(--compare-b-soft);stroke:var(--compare-b)\" stroke-width=\"1.5\"/\u003e\u003ctext x=\"497\" y=\"149\" text-anchor=\"middle\" style=\"fill:var(--content)\" font-family=\"ui-monospace,monospace\" font-size=\"11\"\u003eHashMap\u003c/text\u003e\u003crect x=\"372\" y=\"172\" width=\"55\" height=\"40\" rx=\"4\" style=\"fill:var(--compare-b-soft);stroke:var(--compare-b)\" stroke-width=\"1.5\"/\u003e\u003ctext x=\"399\" y=\"196\" text-anchor=\"middle\" style=\"fill:var(--content)\" font-family=\"ui-monospace,monospace\" font-size=\"11\"\u003eBox\u003c/text\u003e\u003crect x=\"437\" y=\"184\" width=\"50\" height=\"28\" rx=\"3\" style=\"fill:none;stroke:var(--border)\" stroke-width=\"1\" stroke-dasharray=\"3,2\"/\u003e\u003ctext x=\"462\" y=\"201\" text-anchor=\"middle\" style=\"fill:var(--secondary)\" font-family=\"ui-monospace,monospace\" font-size=\"9\"\u003efree\u003c/text\u003e\u003crect x=\"372\" y=\"224\" width=\"130\" height=\"46\" rx=\"4\" style=\"fill:var(--compare-b-soft);stroke:var(--compare-b)\" stroke-width=\"1.5\"/\u003e\u003ctext x=\"437\" y=\"251\" text-anchor=\"middle\" style=\"fill:var(--content)\" font-family=\"ui-monospace,monospace\" font-size=\"11\"\u003eString data\u003c/text\u003e\u003crect x=\"512\" y=\"228\" width=\"60\" height=\"35\" rx=\"4\" style=\"fill:var(--compare-b-soft);stroke:var(--compare-b)\" stroke-width=\"1.5\"/\u003e\u003ctext x=\"542\" y=\"250\" text-anchor=\"middle\" style=\"fill:var(--content)\" font-family=\"ui-monospace,monospace\" font-size=\"11\"\u003eArc\u003c/text\u003e\u003ctext x=\"480\" y=\"326\" text-anchor=\"middle\" style=\"fill:var(--compare-b)\" font-family=\"ui-monospace,monospace\" font-size=\"10\" font-weight=\"600\"\u003emanual/GC · flexible · fragments\u003c/text\u003e\u003ctext x=\"480\" y=\"341\" text-anchor=\"middle\" style=\"fill:var(--secondary)\" font-family=\"ui-monospace,monospace\" font-size=\"9\"\u003elimited by OS / RAM\u003c/text\u003e\u003c/svg\u003e\n\u003c/div\u003e\n\u003ch2 id=\"comparison-table\"\u003eComparison Table\u003c/h2\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003eAspect\u003c/th\u003e\n          \u003cth\u003eStack\u003c/th\u003e\n          \u003cth\u003eHeap\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eAllocation mechanism\u003c/td\u003e\n          \u003ctd\u003ePointer decrement — O(1), no bookkeeping\u003c/td\u003e\n          \u003ctd\u003eAllocator call (malloc/new) — higher constant, free-list bookkeeping\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eDeallocation\u003c/td\u003e\n          \u003ctd\u003eAutomatic on scope/frame exit\u003c/td\u003e\n          \u003ctd\u003eExplicit (free/delete) or garbage collector\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eData lifetime\u003c/td\u003e\n          \u003ctd\u003eBound to the declaring scope or call frame\u003c/td\u003e\n          \u003ctd\u003eArbitrary; can outlive any function call\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eSize constraint\u003c/td\u003e\n          \u003ctd\u003eFixed at thread creation (typically 1–8 MB)\u003c/td\u003e\n          \u003ctd\u003eLimited only by available virtual memory / RAM\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eSize known at compile time\u003c/td\u003e\n          \u003ctd\u003eRequired — compiler must know the type\u0026rsquo;s layout\u003c/td\u003e\n          \u003ctd\u003eNot required — length/capacity decided at runtime\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eFragmentation\u003c/td\u003e\n          \u003ctd\u003eNone — LIFO order keeps allocation contiguous\u003c/td\u003e\n          \u003ctd\u003eYes — internal and external fragmentation accumulate over time\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eThread ownership\u003c/td\u003e\n          \u003ctd\u003eEach thread has its own stack; no synchronization needed\u003c/td\u003e\n          \u003ctd\u003eShared across threads; allocator must serialize internally\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eFailure mode\u003c/td\u003e\n          \u003ctd\u003eStack overflow → immediate crash (SIGSEGV/signal)\u003c/td\u003e\n          \u003ctd\u003eOOM → null / exception / OOM-killer; potentially recoverable\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch2 id=\"key-differences\"\u003eKey Differences\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eStack allocation is a single SP register decrement; heap allocation invokes an allocator with metadata updates, free-list traversal, and possible OS syscalls.\u003c/li\u003e\n\u003cli\u003eStack lifetime is strictly scoped to the function frame — data cannot be returned by pointer from the stack safely; heap memory can be returned, stored globally, or transferred across threads.\u003c/li\u003e\n\u003cli\u003eEach thread has its own stack and needs no locking; the heap is process-wide and requires allocator-level synchronization on every alloc/free.\u003c/li\u003e\n\u003cli\u003eStack size is fixed and small (set by the OS or linker script); heap can grow dynamically, making it the only viable region for large buffers or runtime-sized collections.\u003c/li\u003e\n\u003cli\u003eHeap fragmentation is a real operational concern in long-lived or allocation-heavy processes; the stack never fragments because it always grows and shrinks from one end in LIFO order.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"when-to-use-each\"\u003eWhen to Use Each\u003c/h2\u003e\n\u003cp\u003e\u003cstrong\u003eStack\u003c/strong\u003e — Prefer the stack for local variables, function arguments, and fixed-size value types whose lifetime is bounded by the enclosing scope — it is faster, deterministic, and eliminates entire classes of memory bugs.\u003c/p\u003e","title":"Stack vs Heap: Memory Allocation Models"}]