Node.js is single-threaded for JavaScript, but it handles concurrency smartly thanks to libuv and the Event Loop. Here’s the reality: 1. Network I/O (Best Use Case) • Truly asynchronous using OS-level mechanisms (epoll/kqueue/IOCP). • No extra threads needed. • Best Practice: Always use async/await with HTTP, database drivers, and external APIs. Keep the Event Loop free. 2. File I/O • Offloaded to libuv’s internal thread pool (default only 4 threads). • Best Practice: Use fs.promises, Streams for large files, and consider increasing UV_THREADPOOL_SIZE (e.g. 8–16) based on your workload. 3. CPU-Heavy Tasks • Runs directly on the main Event Loop → can block the entire application. • Best Practice: Never block the loop. Offload heavy computations to Worker Threads or separate microservices (Go/Rust/.NET). Key Takeaway: Node.js excels at Network I/O, but you must carefully offload File I/O and especially CPU-bound work to maintain high performance and low latency.
Node.js Performance: Best Practices for I/O and CPU-Heavy Tasks
More Relevant Posts
-
What async actually changed in JavaScript 🔄 Joshua Segall takes a step back on the evolution of async in JavaScript, from callbacks to promises to async/await. Each step solved a real problem, but also introduced new trade-offs that are still visible today. Async/await made code easier to read by giving it a sequential feel. The downside is that it can hide what really matters in concurrent systems : which operations depend on each other and which could run in parallel. What looks simple on the surface can become harder to reason about as complexity grows. Async did not remove complexity, it just made it less visible. Understanding execution flow and dependencies still matters as systems grow. A thoughtful read if you work with async code daily and want a clearer mental model of what is really going on under the hood. ↙️ https://lnkd.in/exxsrMA8
To view or add a comment, sign in
-
“JavaScript is single-threaded… so how does Node.js handle thousands of requests?” This confused me for a long time. The short answer: it doesn't do everything itself. Node.js uses something called the event loop to stay fast and scalable. Here's the simple mental model 👉 JavaScript runs on a single main thread 👉 But it doesn' wait for slow operations When a task like: • API call • Database query • File read comes in… ➡️ It's offloaded to the system (via the event loop / background workers) ➡️ The main thread keeps moving forward ➡️ When the result is ready, it gets picked up and processed Why this feels fast Nothing is blocking the main thread. So instead of doing: "Do task → wait → next task" Node does: "Start task → move on → come back when ready" What this unlocks ✔ Handles thousands of concurrent requests ✔ Efficient for I/O-heavy apps (APIs, streaming, real-time systems) ✔ Better resource utilization Important nuance Node.js is not magically multi-threaded for your code. It's non-blocking, not parallel (by default). Heavy CPU tasks can still slow it down— but for most web workloads, this model works extremely well. Why it's still so popular Despite newer languages like Go or Java offering different models: 👉 JavaScript has a massive ecosystem 👉 Full-stack development becomes easier 👉 With TypeScript, it's become even more robust The takeaway Node.js wins not because it's single-threaded— but because it doesn't waste time waiting. Comment, Share,♻️ Repost it to your network if you liked and follow Daniyaal Saifee Nayeem for more.
To view or add a comment, sign in
-
-
I removed Express from my Node.js project. Then removed the http module too. Built everything from raw TCP and finally understood what was actually happening. Three things that clicked: → request.body is a stream, not a property Node reads your request in chunks. That’s why even very large uploads don’t crash your server. → GET, POST, and PUT are not interchangeable Send the same POST twice, two records get created. Send PUT twice, nothing changes. That difference has a name: idempotency. → Postman is just a GUI Every button maps to three things: method, headers, and body. Wrote a 4-part breakdown. #NodeJS #JavaScript #BackendDevelopment #medium Read the full article here: https://lnkd.in/dWQRp7Ta
To view or add a comment, sign in
-
Ever wonder what's actually happening under the hood when Promise.all executes your parallel API calls? Here's the magic: libuv. Node.js doesn't run requests in parallel on a single thread. Instead: 1. Thread Pool — libuv queues your requests to worker threads (default 4). 2. OS Multiplexing — epoll/kqueue monitors network sockets simultaneously. 3. Event Loop — The main thread stays responsive, orchestrating callbacks. When you fire 3 API calls with Promise.all, libuv: - Registers them with the OS. - Worker threads handle DNS/I/O in parallel. - The event loop waits for responses (non-blocking). - Callbacks fire when data arrives. The result? True concurrency without blocking the main thread. This is why JavaScript can handle thousands of concurrent connections despite being single-threaded. Understanding libuv is key to understanding modern Node.js. #NodeJS #JavaScript #SystemArchitecture #Backend
To view or add a comment, sign in
-
Node.js is single-threaded.That's both true and a lie. Let me explain. Lets say you have one best friend and also have 4 close friends. if anyone say you have only one friend. what your answers will be ? Lets understand the concept in JS way. we all know JavaScript is a single threaded means it can only execute one task at a time but how JS then efficiently handle the network tasks , file read or db query ? Js just give those tasks to one of its close friend name libuv(a library written in c++ who handle async tasks) which has default 4 threads. Is this the end? what if a task that is not a network call , file read ? but the task will take decent amount of time which is enough to block the main thread doing other tasks, lets assume you are resizing a large image. now what will you do? will you leave the JS alone although JS will not be alone. You will use Worker Threads so you can give the heavy task to worker threads and keep your main thread free and do other tasks As we are using multi-threading then a concept come how to handle the race condition then. for worker threads we don't have to think about race condition due to isolation of the memory.
To view or add a comment, sign in
-
await doesn't magically make your code async. A lot of devs get this wrong early on. Here's how Node.js actually works: Node.js runs on a single thread. That one thread handles everything. Block it and your whole server freezes. There are 3 things you need to understand: 1. The Main Thread (Event Loop) This is Node's brain. It picks up requests, runs your JS, and moves on. Keep it free. Always. 2. The Thread Pool (libuv) Heavy work like file reads, crypto, DNS lookups? Node quietly offloads these to a pool of background threads. Your main thread stays free while they work. 3. OS Kernel (for network I/O) Things like HTTP requests, TCP connections? These don't even touch the thread pool. The OS handles them directly. Node just waits for a signal. So what actually blocks the server? Sync loops. Heavy CPU math. Blocking file reads. These run on the main thread and nothing else runs until they're done. Think of Node as a chef in a busy kitchen. CPU-heavy task? Chef does it alone. Nobody else gets served. File/crypto task? Sent to kitchen helpers (thread pool). Chef stays free. Network call? The delivery guy handles it (OS). Chef doesn't even think about it. Promise/timer callback? Chef checks the notes between orders. Fast. Non-blocking unless the note says "cook a 5-course meal." One most important thing: Even async code can block. If your Promise callback runs a heavy sync task — it still runs on the main thread. The scheduling is async. The execution isn't. await just tells JS: "I'll wait for this but don't freeze while you do." #NodeJS #JavaScript #BackendDevelopment #SoftwareEngineering
To view or add a comment, sign in
-
-
Node.js 24.15.0 (LTS) shipped last week and landed in this Monday's JavaScript Weekly: require(esm) and the module compile cache are now marked stable. This means you can require() ES modules from CommonJS code in production without flags, warnings, or experimental caveats. The module compile cache — which eliminates repeated parsing of the same modules — is also stable, cutting cold-start times for ESM-heavy applications. A new --max-heap-size CLI flag rounds out the release. Source: https://lnkd.in/eqaAnKXk
To view or add a comment, sign in
-
-
Node.js Worker Threads: True Multi-Threading for Your JavaScript Code Node.js is recognized for its efficient handling of I/O through the Event Loop and the UV_THREADPOOL for system-level tasks. However, when JavaScript code becomes the bottleneck, Worker Threads are essential. 🧠 Core Concepts: - Isolated Execution: Each worker operates in its own V8 instance with separate memory, functioning like lightweight parallel Node.js instances. - True Parallelism: Unlike the Event Loop, which is concurrent, Worker Threads enable parallel execution by utilizing multiple CPU cores. - Message-Based Communication: Workers communicate via postMessage(), ensuring no shared state by default, which reduces race conditions. 🛠 When to use them? - Avoid using Worker Threads for I/O, as the Event Loop is more efficient for that. Instead, utilize them for CPU-bound tasks that could otherwise "freeze" your app: - Heavy Math: Complex calculations or data science in JavaScript. - Data Parsing: Transforming large JSON or CSV files. - Image/Video: Processing buffers or generating reports. Key Takeaway: The Thread Pool manages system tasks, while Worker Threads enhance the performance of your JavaScript code. #NodeJS #Backend #Javascript #WebDev #SoftwareEngineering #Performance
To view or add a comment, sign in
-
-
TypeScript 6.0 dropped. Here's what actually matters for your project 🧵 🆕 What's new: • Temporal API types (finally Stage 4!) • Map.getOrInsert() — upsert in one line • RegExp.escape() — safe regex from user input • dom.iterable is now included in dom automatically • Subpath imports with #/ prefix ⚠️ New defaults that will break things: • strict is now TRUE by default • types defaults to [] — add "node" explicitly or things will go missing • rootDir defaults to "." • module defaults to esnext ❌ Start removing these now (gone in TS 7.0): • baseUrl • moduleResolution: node • target: es5 • module: amd/umd/systemjs • outFile TS 6.0 is a transition release — the real target is 7.0 with parallel type checking and a native compiler port. If you're seeing deprecation warnings after upgrading: fix them now, not later. What's your migration plan? Drop it in the comments 👇 #TypeScript #JavaScript #WebDevelopment #Frontend
To view or add a comment, sign in
-
𝗧𝗦 𝟲.𝟬 𝗗𝗘𝗘𝗣 𝗗𝗜𝗩𝗘 | 𝗣𝗮𝗿𝘁 𝟮 𝗼𝗳 𝟱 We’ve been dragging ES5 support around like a heavy anchor for years. TypeScript 6 is finally cutting the rope. TypeScript 6 is doing the dirty work nobody wanted to do: killing off legacy standards that have been bloating our configurations for a decade. If you want your codebase ready for the version 7.0 "𝗚𝗼" rewrite, you need to stop clinging to the past. Microsoft is making it clear: modern ESM is the only way forward. Here is what’s officially on the chopping block and why you should be happy about it: → Goodbye, target: 𝗘𝗦𝟱 We are finally moving past the IE11 era. By dropping ES5 support, the compiler no longer has to carry the logic for translating modern syntax into 2009-era JavaScript. This simplifies the emit process and lightens the load on the compiler. → The end of 𝗔𝗠𝗗, 𝗨𝗠𝗗, and 𝗦𝘆𝘀𝘁𝗲𝗺𝗝𝗦 Unless you’re maintaining a library from 2014, you shouldn't be using these module formats. Moving to strictly ES Modules (ESM) makes your dependency tree cleaner and significantly faster to crawl. → Phasing out 𝗯𝗮𝘀𝗲𝗨𝗿𝗹 For years, baseUrl was the hack to avoid deeply nested imports (../../../). TS 6 pushes us toward native Node Subpath Imports. Instead of TypeScript-specific magic, you now use standard package.json imports (e.g., mapping #components/* instead of relying on compiler aliases). The Bottom Line: This isn't just about deprecating old tech. Every legacy feature the TypeScript team removes is one less edge case they have to account for in the upcoming Go-based compiler. Less legacy baggage = faster builds = better developer experience. If your tsconfig.json still looks like a time capsule from 2018, now is the time to audit it. 🗣️ What’s the one piece of "legacy" tech you’re still forced to support in your current project? #TypeScript #WebDevelopment #SoftwareEngineering #CleanCode
To view or add a comment, sign in
-
Explore content categories
- Career
- Productivity
- Finance
- Soft Skills & Emotional Intelligence
- Project Management
- Education
- Technology
- Leadership
- Ecommerce
- User Experience
- Recruitment & HR
- Customer Experience
- Real Estate
- Marketing
- Sales
- Retail & Merchandising
- Science
- Supply Chain Management
- Future Of Work
- Consulting
- Writing
- Economics
- Artificial Intelligence
- Employee Experience
- Workplace Trends
- Fundraising
- Networking
- Corporate Social Responsibility
- Negotiation
- Communication
- Engineering
- Hospitality & Tourism
- Business Strategy
- Change Management
- Organizational Culture
- Design
- Innovation
- Event Planning
- Training & Development
While Worker Threads are great for offloading heavy CPU computations, many developers overlook Node.js Cluster for a different but very common use case. Node Cluster allows you to run multiple instances of your application (each with its own Event Loop) across all CPU cores. Use Cluster when: • Your app is primarily I/O-bound (Network + Database) • You want to maximize CPU utilization without complex code changes • You need simple horizontal scaling within a single machine Use Worker Threads when: • You have actual CPU-intensive tasks (image processing, heavy calculations, data transformation, etc.) In most production web APIs, Cluster (or PM2 cluster mode) is the more common and simpler choice. Worker Threads are better reserved for specific heavy background jobs.