<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Software Jutsu</title>
    <description>The latest articles on Forem by Software Jutsu (@softwarejutsu).</description>
    <link>https://forem.com/softwarejutsu</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3264952%2Fd1583725-02b2-452e-9f54-0d8be2196a10.png</url>
      <title>Forem: Software Jutsu</title>
      <link>https://forem.com/softwarejutsu</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/softwarejutsu"/>
    <language>en</language>
    <item>
      <title>AWS X-Ray</title>
      <dc:creator>Software Jutsu</dc:creator>
      <pubDate>Tue, 03 Mar 2026 09:23:34 +0000</pubDate>
      <link>https://forem.com/softwarejutsu/aws-x-ray-201d</link>
      <guid>https://forem.com/softwarejutsu/aws-x-ray-201d</guid>
      <description>&lt;p&gt;In the modern landscape of cloud application development, the monolithic architecture has largely given way to microservices.&lt;/p&gt;

&lt;p&gt;This approach, which involves breaking down applications into a collection of smaller, loosely coupled, and independently deployable services, has revolutionized the industry by offering unparalleled benefits in scalability, fault tolerance, and development speed.However, this architectural shift introduces a new, and critical, challenge: observability. &lt;/p&gt;

&lt;p&gt;In a microservices ecosystem, a single user request can traverse a complex and often invisible web of services, databases, and third party APIs. When something goes wrong, be it a sudden spike in latency, an unusual error, or a performance bottleneck it can be incredibly difficult to answer the question, &lt;br&gt;
"Where is the problem coming from?"&lt;/p&gt;

&lt;p&gt;Traditional monitoring tools, while adept at monitoring individual service health, fall short in this environment. They provide a siloed view of the world, making it almost impossible to understand how an issue in one service might be impacting another. &lt;/p&gt;

&lt;p&gt;This is where &lt;strong&gt;AWS X-Ray&lt;/strong&gt; steps in.&lt;/p&gt;




&lt;h2&gt;
  
  
  Solution to the microservices observability problem.
&lt;/h2&gt;

&lt;p&gt;It’s a powerful distributed tracing service that allows developers to "see" inside their applications, trace the path of a request as it moves from one service to another, and visualize the entire application architecture in real-time. By providing this end-to-end visibility, X-Ray empowers development teams to move beyond mere monitoring and embrace true observability.&lt;/p&gt;

&lt;p&gt;It transforms your application from a collection of "black boxes" into a transparent, understandable, and ultimately, a more reliable system. This article will serve as your comprehensive guide to understanding, deploying, and maximizing the value of AWS X-Ray in your environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem of Visibility in a Microservices World
&lt;/h2&gt;

&lt;p&gt;Before we dive into how X-Ray works, it’s important to fully appreciate the problem it solves. To illustrate, imagine a simple e-commerce application. In a monolithic architecture, a user request to "place an order" is a single, self-contained unit of work. If it's slow, you can examine the application logs for that specific request and pinpoint the slow database query or the inefficient loop within your code.&lt;/p&gt;

&lt;p&gt;Now, consider the same application in a microservices environment. A user’s "place order" request might touch: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An API Gateway (the entry point)&lt;/li&gt;
&lt;li&gt;An Authentication Service (to verify the user)&lt;/li&gt;
&lt;li&gt;An Inventory Service (to check stock)&lt;/li&gt;
&lt;li&gt;A Payment Processing Service (to handle the transaction)&lt;/li&gt;
&lt;li&gt;A Shipping Service (to generate a label)&lt;/li&gt;
&lt;li&gt;A Database (used by the Inventory Service)&lt;/li&gt;
&lt;li&gt;An External Third-Party API (used by the Payment Service)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When that request takes 10 seconds to complete, where is the bottleneck?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is the &lt;strong&gt;Authentication Service&lt;/strong&gt; taking too long to connect to its user database?&lt;/li&gt;
&lt;li&gt;Did the &lt;strong&gt;Payment Service&lt;/strong&gt; hang while waiting for a response from the external API?&lt;/li&gt;
&lt;li&gt;Is the &lt;strong&gt;Inventory Service&lt;/strong&gt; running an inefficient SQL query?&lt;/li&gt;
&lt;li&gt;Was the network latency between the &lt;strong&gt;Shipping Service&lt;/strong&gt; and its database unusually high?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without a way to trace the request, answering these questions is a nightmare. It requires you to log into each individual service, manually correlate the logs based on time (which is notoriously difficult), and "hope" you can piece the puzzle together. &lt;br&gt;
This approach is slow, error-prone, and unsustainable.&lt;/p&gt;

&lt;p&gt;X-Ray provides the "missing link"&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Understanding the Key Concepts of AWS X-Ray&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;X-Ray is built on a few core concepts that work together to provide this distributed visibility. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Segments&lt;/strong&gt;&lt;br&gt;
A segment represents a logical unit of work performed by a single service in response to a request. When a request hits your application, the first service it encounters creates a parent segment. This segment records metadata about the service itself (its name, host, etc.) and information about the incoming request (the HTTP method, URL, and client IP). &lt;br&gt;
As that service performs its internal processing, the segment grows. If the service then makes a call to another component—like a database, an S3 bucket, or another microservice, it creates a subsegment within that segment.&lt;br&gt;
Essentially, a segment tells you what an individual service did and how long it took.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Subsegments&lt;/strong&gt;&lt;br&gt;
Subsegments provide a more granular view of the operations within a service. They are created when a service interacts with other downstream resources. They are crucial for breaking down the total time spent in a service. &lt;/p&gt;

&lt;p&gt;For example, a subsegment might represent:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A database query: Recording the query type, the table name, and the time the query took to execute.&lt;/li&gt;
&lt;li&gt;An HTTP client call: Recording the URL being called and the status code returned.&lt;/li&gt;
&lt;li&gt;An AWS SDK call: Recording the specific AWS service and action (e.g., s3.PutObject).&lt;/li&gt;
&lt;li&gt;A custom code block: You can even create subsegments for specific, long-running functions within your own code to measure their performance.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Subsegments can be nested within each other, creating a detailed, hierarchical "flame graph" of activity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Traces&lt;/strong&gt;&lt;br&gt;
A trace is the most important concept in X-Ray. It is the end-to-end "story" of a request. A trace is a collection of all the segments and subsegments from all the different services that participated in fulfilling that single request.&lt;br&gt;
Each trace has a unique Trace ID, which is generated by the first service that receives the request. This Trace ID is then passed down to all subsequent services in an HTTP header (the X-Amzn-Trace-Id header). &lt;/p&gt;

&lt;p&gt;This correlation mechanism is what stitches all the segments together into a single, cohesive view.&lt;br&gt;
A trace allows you to follow the request’s complete journey, from the moment it arrived at your application to the final response.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Annotations and Metadata&lt;/strong&gt;&lt;br&gt;
To make your traces even more powerful, you can add custom information to them. X-Ray provides two ways to do this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Annotations: These are key-value pairs with indexed values. You can use annotations to add business-relevant context to a trace, such as the customer ID, the product ID, or a unique transaction ID. Because they are indexed, you can search and filter your traces in the X-Ray console using these values. (e.g., "Show me all traces for CustomerID=123").&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Metadata: These are also key-value pairs, but they are not indexed. They can contain larger, more complex data structures like JSON objects. While you can't search on them, they are invaluable for storing detailed context about a trace that you might want to review when inspecting a specific request. (e.g., a copy of a large request payload).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Annotations are for &lt;strong&gt;filtering&lt;/strong&gt;; Metadata is for &lt;strong&gt;context&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;How AWS X-Ray Work: The Flow of Data&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;To understand how X-Ray gets its data, we need to look at the X-Ray architecture. The process is designed to be highly efficient and asynchronous, ensuring that it adds minimal overhead to your application's performance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The X-Ray SDK&lt;/strong&gt;&lt;br&gt;
The foundation of the entire system is the X-Ray SDK. This SDK must be included as a library within your application’s code. It's available for all major programming languages, including Java, Python, Node.js, Ruby, and .NET.&lt;/p&gt;

&lt;p&gt;The SDK does the heavy lifting of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Generating the initial Trace ID.Creating the initial segment.&lt;/li&gt;
&lt;li&gt;Automatically creating subsegments for supported libraries (like database drivers and AWS SDKs).&lt;/li&gt;
&lt;li&gt;Propagating the Trace ID to downstream services in the X-Amzn-Trace-Id header.&lt;/li&gt;
&lt;li&gt;Buffering the collected segments and subsegments.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The X-Ray Daemon&lt;/strong&gt;&lt;br&gt;
The X-Ray SDK doesn't send data directly to the X-Ray API. Instead, it sends the buffered data (via UDP) to a local process called the X-Ray Daemon.&lt;/p&gt;

&lt;p&gt;The daemon is designed to run close to your application. It can run as a background process on an EC2 instance, as a sidecar container in an ECS task or Kubernetes pod, or as a component within a Lambda function.&lt;/p&gt;

&lt;p&gt;The daemon acts as a data aggregator and forwarder. It collects data from multiple SDK instances, batches it, and securely transmits it to the X-Ray API over HTTPS.&lt;br&gt;
This asynchronous, buffered design ensures that your application's request-processing code is not blocked by network calls to the X-Ray service.&lt;/p&gt;

&lt;p&gt;For serverless environments like AWS Lambda, you don't need to manually install the daemon. Instead, you simply "tick a box" in the Lambda configuration, and AWS manages the daemon for you.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Putting it into Action: Instrumenting Your Application&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Getting started with X-Ray involves a process called "instrumentation," which is the process of adding the X-Ray SDK to your application. &lt;/p&gt;

&lt;p&gt;While this sounds complex, AWS has worked hard to make it as simple and automatic as possible.There are three main levels of instrumentation:&lt;br&gt;
&lt;strong&gt;1. Zero-Code Instrumentation (For Containerized/EC2 Workloads)&lt;/strong&gt;&lt;br&gt;
This is the easiest path. You can use an X-Ray-compatible agent or the AWS Distro for OpenTelemetry (ADOT) to automatically instrument your application.&lt;/p&gt;

&lt;p&gt;ADOT is a highly recommended approach. It’s an AWS-supported, production-ready distribution of the OpenTelemetry project. By using the ADOT Collector and language SDKs, you can collect traces from your application with almost zero code changes. You simply configure your container to include the ADOT agent, and it automatically handles the collection and propagation of trace data to X-Ray. &lt;/p&gt;

&lt;p&gt;This is a fantastic way to quickly add observability to existing applications without rewriting them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. SDK-Based Auto-Instrumentation&lt;/strong&gt;&lt;br&gt;
For more control, or when auto-instrumentation agents aren't supported, you can use the X-Ray SDK and its language-specific auto-instrumentation libraries.&lt;br&gt;
Most X-Ray SDKs provide integrations for popular frameworks and libraries. For example:&lt;br&gt;
Node.js: You can use aws-xray-sdk-express to automatically trace incoming Express requests.&lt;br&gt;
Python: The aws-xray-sdk can be configured to automatically instrument the boto3 library (the AWS SDK) and common database drivers like SQLAlchemy or psycopg2.This is the most common approach for new applications.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Custom Instrumentation (For Manual Tracing)&lt;/strong&gt;&lt;br&gt;
For granular control, you can use the SDK’s API directly in your code. This allows you to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Manually create subsegments around critical, custom business logic.&lt;/li&gt;
&lt;li&gt;Add annotations and metadata to enrich your traces.&lt;/li&gt;
&lt;li&gt;Capture custom exceptions and errors.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This approach is powerful but requires code changes and is typically used to supplement auto-instrumentation.&lt;/p&gt;




&lt;h2&gt;
  
  
  Beyond Basic Tracing: Advanced Insights
&lt;/h2&gt;

&lt;p&gt;X-Ray isn't just about showing you a list of traces. Its value is magnified by the advanced features that help you analyze and act on that data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Service Map: A Visual Health Dashboard&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The X-Ray Service Map is one of its most powerful features. It’s a dynamic, visual graph that is automatically generated from the trace data it collects.&lt;/p&gt;

&lt;p&gt;The service map provides a bird's-eye view of your entire application architecture. Each node on the map represents a service, and the connections between them show the flow of requests. The map updates in real-time, giving you an immediate sense of the health and relationships between your components.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Root Cause Analysis&lt;/strong&gt;: When a node in the map turns red (due to errors) or orange (due to faults), you can instantly see where the problem is originating.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bottleneck Detection:&lt;/strong&gt; The thickness of the connections between services represents the volume of traffic, while the color can indicate latency. This makes it easy to spot over-utilized services or network bottlenecks.&lt;/p&gt;




&lt;h2&gt;
  
  
  CloudWatch ServiceLens
&lt;/h2&gt;

&lt;p&gt;While X-Ray is powerful on its own, its true potential is unlocked when it’s integrated with other AWS services. This is the core concept behind CloudWatch ServiceLens.&lt;/p&gt;

&lt;p&gt;ServiceLens is an observability hub that integrates &lt;br&gt;
traces (from X-Ray), &lt;br&gt;
metrics (from CloudWatch Metrics), &lt;br&gt;
and logs (from CloudWatch Logs) &lt;br&gt;
into a single, unified view.&lt;/p&gt;

&lt;p&gt;Imagine you see an error spike on the Service Map.&lt;br&gt;
You click on the error node to see a list of the specific traces that failed.&lt;br&gt;
You select a trace to see its detailed end-to-end timeline and find the failing segment.&lt;/p&gt;

&lt;p&gt;ServiceLens can then show you the actual CloudWatch logs for that specific request from that specific service, correlated by the Trace ID.&lt;/p&gt;

&lt;p&gt;This gives you ability to seamlessly traverse from metric to trace to log, save time and frustration during incident response.&lt;/p&gt;

&lt;h2&gt;
  
  
  X-Ray Insights: Proactive Issue Detection
&lt;/h2&gt;

&lt;p&gt;X-Ray Insights is a powerful analysis feature that proactively detects issues in your applications. Instead of waiting for you to find a problem, Insights analyzes your trace data to identify anomalies, such as unexpected spikes in fault rates or significant changes in latency.&lt;/p&gt;

&lt;p&gt;When it detects an issue, it creates an "insight" event that highlights the impacted service and the potential root cause. It also allows you to compare the current trace data with past performance to understand the scope of the change. &lt;/p&gt;

&lt;p&gt;This proactive detection is crucial for identifying problems before they impact users.&lt;/p&gt;

&lt;p&gt;Conclusion&lt;/p&gt;

&lt;p&gt;In the world of microservices, observability is no longer an optional "nice-to-have." It is a fundamental requirement for building, deploying, and operating reliable applications.&lt;/p&gt;

&lt;p&gt;AWS X-Ray provides the tools you need to overcome the visibility challenges inherent in distributed systems. By offering end-to-end tracing, a visual service map, and powerful integrations with the broader CloudWatch ecosystem, X-Ray transforms your application from a confusing black box into a clear, understandable, and manageable system.&lt;/p&gt;

&lt;p&gt;While implementing distributed tracing requires an investment in instrumentation, the returns—in terms of faster mean-time-to-resolution (MTTR), improved performance, and a better understanding of your application—are invaluable. In a maze of microservices, AWS X-Ray is the map and compass that every modern development team needs.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>xray</category>
      <category>log</category>
    </item>
    <item>
      <title>Token Pruning and Prompt Compression in Modern AI</title>
      <dc:creator>Software Jutsu</dc:creator>
      <pubDate>Sat, 14 Feb 2026 22:10:55 +0000</pubDate>
      <link>https://forem.com/softwarejutsu/token-pruning-and-prompt-compression-in-modern-ai-h0o</link>
      <guid>https://forem.com/softwarejutsu/token-pruning-and-prompt-compression-in-modern-ai-h0o</guid>
      <description>&lt;p&gt;In the landscape of Large Language Models (LLMs), "context is king," but context is also expensive. &lt;br&gt;
As we move toward models with million-token windows, the efficiency of how we fill that space has become a critical engineering hurdle.&lt;/p&gt;

&lt;p&gt;Token pruning and prompt compression have emerged as the primary solutions to the "bloated prompt" problem.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is Token Pruning?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Token pruning&lt;/strong&gt; is the process of identifying and removing redundant, less informative, or "noisy" tokens from a prompt before or during the inference phase.&lt;/p&gt;

&lt;p&gt;Unlike simple summarization, which rewrites text to be shorter, pruning often involves algorithmic selection—deciding which specific tokens the model's attention mechanism can afford to ignore without losing the semantic "gist" of the message.&lt;/p&gt;

&lt;h3&gt;
  
  
  How it works
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Importance Scoring:&lt;/strong&gt; The system assigns a "budget" to the prompt. It uses a smaller, faster model (like a BERT-base or a lightweight GPT) to calculate the perplexity or attention weight of each token.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Filtering:&lt;/strong&gt; Tokens with low importance scores (e.g., "the," "actually," redundant adjectives, or repetitive background info) are discarded.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Re-alignment:&lt;/strong&gt; The remaining tokens are concatenated into a condensed string that is then passed to the primary, high-performance LLM (like GPT-4o or Gemini 1.5 Pro).&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Usage Scenarios
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. The RAG "Needle in a Haystack"
&lt;/h3&gt;

&lt;p&gt;In Retrieval-Augmented Generation (RAG), a system might pull 10 different PDFs to answer one question. This creates a massive prompt where 90% of the text is irrelevant. &lt;/p&gt;

&lt;p&gt;Pruning allows the model to focus its "attention heads" specifically on the relevant paragraphs. &lt;/p&gt;

&lt;p&gt;It mitigates the &lt;strong&gt;"Lost in the Middle"&lt;/strong&gt; phenomenon, where models perform worse when key information is buried in the center of a long prompt.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Infinite-Turn Conversations
&lt;/h3&gt;

&lt;p&gt;Customer service bots or roleplay AI often accumulate massive chat histories. If you don't prune, the cost per message increases linearly until the model hits its limit and starts "forgetting" the beginning of the interaction.&lt;/p&gt;

&lt;p&gt;By pruning 30-50% of the middle-history tokens, you can maintain factual consistency of a conversation for thousands of turns at a fixed cost.&lt;/p&gt;




&lt;h2&gt;
  
  
  Scenario Example: Legal Document Analysis
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The Setup:&lt;/strong&gt;&lt;br&gt;
A law firm needs to use an LLM to find conflicting clauses across five different 50-page contracts (approx. 60,000 tokens).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Without Token Pruning:&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Cost&lt;/strong&gt;: Processing 60,000 tokens per query costs roughly $0.15 - $0.60 (depending on the model).&lt;br&gt;
&lt;strong&gt;Latency:&lt;/strong&gt; The model takes 30-40 seconds to process the "prefill" (reading the prompt).&lt;br&gt;
&lt;strong&gt;Risk:&lt;/strong&gt; The model might hallucinate or miss a conflict because the relevant clauses are buried under 40 pages of standard "boilerplate" definitions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;With Token Pruning (using a tool like LLMLingua):&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Preprocessing:&lt;/strong&gt; A small model scans the 60,000 tokens and identifies that 45,000 tokens are "filler" that appears in every contract.&lt;br&gt;
&lt;strong&gt;Compression:&lt;/strong&gt; The prompt is compressed by &lt;strong&gt;4x&lt;/strong&gt;, leaving only 15,000 tokens containing the unique, substantive clauses.&lt;br&gt;
&lt;strong&gt;Result:&lt;/strong&gt; * &lt;strong&gt;Cost&lt;/strong&gt; drops by 75%.&lt;br&gt;
&lt;strong&gt;Latency&lt;/strong&gt; improves significantly as the "prefill" time is slashed.&lt;br&gt;
&lt;strong&gt;Accuracy&lt;/strong&gt; increases because the LLM's attention is focused solely on the unique variables of the contracts.&lt;/p&gt;




&lt;p&gt;Optimizing Gemini with Token Pruning&lt;/p&gt;

&lt;p&gt;When using LLM in your projects, it does not prune tokens automatically, you should implement one of the following strategies in your application layer, lets say using Gemini&lt;/p&gt;

&lt;h2&gt;
  
  
  Strategy A: The "Semantic Filter"
&lt;/h2&gt;

&lt;p&gt;Use a lightweight tool like &lt;strong&gt;LLMLingua&lt;/strong&gt; or a smaller model (like &lt;strong&gt;Gemini 1.5 Flash-Lite&lt;/strong&gt;) to "compress" your prompt before sending it to the more expensive &lt;strong&gt;Gemini 1.5 Pro&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Implementation Steps:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Scoring:&lt;/strong&gt; Calculate the "importance" of each sentence or paragraph relative to the user's query.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pruning:&lt;/strong&gt; Remove segments with low importance scores.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Inference:&lt;/strong&gt; Send the compressed prompt to the Gemini API.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Strategy B: Hard Truncation &amp;amp; Summarization
&lt;/h2&gt;

&lt;p&gt;For chat history, don't just send the last 100 messages. &lt;br&gt;
&lt;strong&gt;Pruning Logic:&lt;/strong&gt; Keep the last 5 messages in full. For messages 6-50, provide a &lt;strong&gt;one-sentence summary&lt;/strong&gt; of each exchange rather than the full transcript.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; Use the &lt;code&gt;count_tokens&lt;/code&gt; method in the Gemini SDK before sending a request to monitor how much your pruning is actually saving you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pruning vs. Summarization
&lt;/h2&gt;

&lt;p&gt;Pruning is different from summarizing.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Token Pruning / Compression&lt;/th&gt;
&lt;th&gt;Standard Summarization&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Logic&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Removes low-entropy tokens algorithmically.&lt;/td&gt;
&lt;td&gt;Rewrites text into a shorter version.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Speed&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Very fast (minimal compute).&lt;/td&gt;
&lt;td&gt;Slower (requires an LLM pass).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Integrity&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Preserves original phrasing of key info.&lt;/td&gt;
&lt;td&gt;May lose specific technical terminology.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Primary Goal&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Cost and Latency reduction.&lt;/td&gt;
&lt;td&gt;Human readability.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Example
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. The Original Prompt (Input)
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;"The system administrator reported that the primary database server, located in the Northern Virginia (us-east-1) region, experienced a critical hardware failure at exactly 14:02:45 UTC. The error log specifically identified a 'TimeoutException' on the NVMe storage controller (Serial: 99-XJ-22). We need to determine if this is a recurring issue across the cluster."&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  2. The Pruned Version (Extractive)
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Logic: Removes "glue" words and low-information adjectives while keeping high-entropy identifiers.&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"administrator reported primary database server us-east-1 experienced critical hardware failure 14:02:45 UTC. error log identified 'TimeoutException' NVMe storage controller Serial: 99-XJ-22. determine recurring issue cluster."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Tokens Saved:&lt;/strong&gt; ~40% reduction.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Human Readability:&lt;/strong&gt; Poor (looks like a telegram).&lt;/li&gt;
&lt;li&gt;The Gemini model still sees the exact timestamp, the exact error code, the exact serial number, and the exact region. It has all the "signal" it needs to solve the problem.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  3. The Summarized Version (Generative)
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Logic: Rewrites the meaning into a new, shorter sentence.&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"The admin noted a hardware crash in the Virginia region at 2:02 PM due to a storage error. We need to check if other servers are affected."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Tokens Saved:&lt;/strong&gt; ~60% reduction.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Human Readability:&lt;/strong&gt; Excellent.&lt;/li&gt;
&lt;li&gt;The exact timestamp (14:02:45) is gone.

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Identifier Loss:&lt;/strong&gt; The specific Serial Number (99-XJ-22) is gone.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Technical Loss:&lt;/strong&gt; "TimeoutException" was replaced with "storage error," which is too vague for troubleshooting.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;p&gt;If you need the model to have 100% of the information but want it to be cheaper/faster, you can try explore Context Caching.&lt;/p&gt;

</description>
      <category>selfnote</category>
    </item>
    <item>
      <title>Amazon Virtual Private Cloud (VPC)</title>
      <dc:creator>Software Jutsu</dc:creator>
      <pubDate>Tue, 10 Feb 2026 05:14:36 +0000</pubDate>
      <link>https://forem.com/softwarejutsu/amazon-virtual-private-cloud-vpc-3996</link>
      <guid>https://forem.com/softwarejutsu/amazon-virtual-private-cloud-vpc-3996</guid>
      <description>&lt;p&gt;An Amazon Virtual Private Cloud (VPC) is a logically isolated section of the Amazon Web Services (AWS) Cloud where you can launch AWS resources in a virtual network that you define. &lt;/p&gt;

&lt;p&gt;It gives you complete control over your virtual networking environment, including the selection of your own IP address range, creation of subnets, and configuration of route tables and network gateways.&lt;/p&gt;

&lt;p&gt;In production deployment it is always best practice to implement VPC for the AWS stacks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why VPC?&lt;/strong&gt;&lt;br&gt;
Creating resources directly on the public cloud without a VPC would be equivalent to placing your laptop on a public sidewalk with no password and a "Free Access" sign. While technically possible in the early days of cloud computing, it poses extreme security and operational risks.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Security and Isolation: Without a VPC, every resource (like a database or a web server) would be assigned a Public IP address by default. This makes them visible and targetable by anyone on the internet. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Connectivity between Services&lt;br&gt;
With VPC, your resource can talk to each other using Private IPs as part of the isolation, on top of that because it communicates via private IPs, it significantly save cost over expensive public IP data transfers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Network Customization: If you created resources directly, you would have no control over the internal networking. In a VPC, you define your own IP address range (e.g., 10.0.0.0/16).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Traffic Routing and Filtering: A VPC allows you to define the "rules of the road" through Route Tables.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Core Components
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;IPv4 and IPv6 Address Blocks: You define a Private IP address range using CIDR notation (e.g., 10.0.0.0/16).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Subnets: A range of IP addresses in your VPC. You can launch AWS resources, like EC2 instances, into a specific subnet.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;-- Public Subnets: Connected to the internet via an Internet Gateway (without gateway you can't connect, its like the physical "door" to the outside world.)&lt;/p&gt;

&lt;p&gt;-- Private Subnets: Not reachable from the public internet; typically used for databases or application servers.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Route Tables: A set of rules (routes) used to determine where network traffic from your subnet or gateway is directed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Internet Gateway (IGW): A horizontally scaled, redundant, and highly available VPC component that allows communication between your VPC and the internet.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;NAT Gateway: Allows instances in a private subnet to connect to the internet (e.g., for software updates) but prevents the internet from initiating a connection with those instances.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Security Layers
&lt;/h2&gt;

&lt;p&gt;AWS VPC provides two features to increase security:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Network Access Control Lists (NACL)&lt;/strong&gt;: An optional layer of security for your VPC that acts as a firewall for controlling traffic in and out of one or more subnets (Stateless).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Security Groups&lt;/strong&gt;: Act as a virtual firewall for your EC2 instances to control inbound and outbound traffic at the instance level (Stateful).&lt;/p&gt;

&lt;h2&gt;
  
  
  Connectivity Options
&lt;/h2&gt;

&lt;p&gt;VPC Peering: A networking connection between two VPCs that enables you to route traffic between them using private IPv4 or IPv6 addresses.&lt;/p&gt;

&lt;p&gt;AWS VPN: Establishes a secure connection between your on-premises network and your Amazon VPC.&lt;/p&gt;

&lt;p&gt;AWS Direct Connect: A cloud service solution that makes it easy to establish a dedicated network connection from your premises to AWS, bypassing the public internet.&lt;/p&gt;

&lt;p&gt;To setup VPC you can follow this&lt;br&gt;
&lt;a href="https://www.youtube.com/watch?v=7_NNlnH7sAg" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=7_NNlnH7sAg&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Pricing
&lt;/h1&gt;

&lt;p&gt;Creating a VPC itself is completely free. You are not charged for defining the network, creating subnets, or setting up Route Tables, Internet Gateways (IGW), or Security Groups.&lt;/p&gt;

&lt;p&gt;However, you pay for the traffic that moves through the VPC and any managed services you attach to it.&lt;/p&gt;

&lt;p&gt;Components That Are Free&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;VPC Creation: No setup or monthly fee.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Subnets &amp;amp; Route Tables: No limit on how many you create for free.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Internet Gateway (IGW): Attaching and using an IGW costs $0.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Network ACLs &amp;amp; Security Groups: Virtual firewalls are provided at no cost.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Components That Cost Money 2026 Jan (Maybe outdated)&lt;/p&gt;

&lt;p&gt;Public IPv4 Address: $0.005 / hour (~$3.60/mo)&lt;/p&gt;

&lt;p&gt;NAT Gateway: $0.045 / hour (~$32/mo), $0.045 per GB processed.&lt;/p&gt;

&lt;p&gt;VPC Interface Endpoint: $0.01 / hour (~$7/mo), $0.01 per GB processed.&lt;/p&gt;

&lt;p&gt;Transit Gateway: $0.05 / hour (per attachment), $0.02 per GB processed.&lt;/p&gt;

&lt;p&gt;Site-to-Site VPN,$0.05 / hour,Standard data transfer rates apply.&lt;/p&gt;

&lt;h2&gt;
  
  
  Data Transfer Costs
&lt;/h2&gt;

&lt;p&gt;This is where most VPC bills grow. AWS charges based on where the data is going.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Inbound Data&lt;/strong&gt;: Always Free (Data coming from the internet into your VPC).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Outbound to Internet&lt;/strong&gt;: Roughly $0.09 per GB (after the first 100GB/month which is free).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Inter&lt;/strong&gt;-Availability Zone (AZ): If you send data between two EC2 instances in different AZs (e.g., US-East-1a to US-East-1b), you pay $0.01 per GB in each direction.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Intra&lt;/strong&gt;-Availability Zone: Sending data between instances in the same AZ using Private IPs is Free.&lt;/p&gt;

&lt;p&gt;Pro Tip: If you use a Public IP to talk to another instance in the same AZ, you will be charged the $0.01/GB rate even though they are in the same building. Always use Private IPs for internal talk.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>vpc</category>
    </item>
    <item>
      <title>Requirement to software Delivery in midsize comp CHEATSHEET</title>
      <dc:creator>Software Jutsu</dc:creator>
      <pubDate>Mon, 12 Jan 2026 03:08:53 +0000</pubDate>
      <link>https://forem.com/softwarejutsu/requirement-to-software-delivery-in-midsize-comp-cheatsheet-2ci1</link>
      <guid>https://forem.com/softwarejutsu/requirement-to-software-delivery-in-midsize-comp-cheatsheet-2ci1</guid>
      <description>&lt;p&gt;In a modern mid-size startup (roughly 50–200 employees), the software development process is designed to balance the speed of a small team with the predictability required by investors and stakeholders. Unlike a "garage startup" that might code on a whim, a mid-size company uses a structured &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Discovery → Planning → Execution loop.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Software development phase (product based delivery) typically involves few phases as following&lt;/p&gt;




&lt;h2&gt;
  
  
  Initiation: "The Why and What"
&lt;/h2&gt;

&lt;p&gt;Initiation is rarely about a single person’s idea; it’s a response to data, customer feedback, or strategic goals.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Catalyst&lt;/strong&gt;: Usually comes from Product Management (PM) (based on user feedback/analytics), Leadership (strategic pivot), or Sales/CS (high-value client requests).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Discovery Phase&lt;/strong&gt;: Before a single line of code is written, a "Discovery" squad (PM, Lead Designer, and Tech Lead) validates the idea. They perform user interviews and technical feasibility spikes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Output: The PRD (Product Requirements Document)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In modern startups, this is a "living" document in Notion or Confluence.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Content&lt;/strong&gt;: Problem statement, target user, user stories, success metrics (KPIs), and "out of scope" items to prevent scope creep.&lt;/p&gt;

&lt;p&gt;Our focus will be on engineering side, so i skip the details of PRD, you will only need to know key parts, normally engineer leads will work very close with Product manager to clarify the PRD contents.&lt;/p&gt;




&lt;h2&gt;
  
  
  Planning: "The How and When"
&lt;/h2&gt;

&lt;p&gt;Once a project is "greenlit" via the PRD, the planning shifts to technical architecture and resource allocation.&lt;br&gt;
UI designers may involved depending on requirement&lt;/p&gt;

&lt;p&gt;Designers receives the PRD analyze the requirement, coming up with solution and provide &lt;strong&gt;Key output: high-fidelity mockups (usually in Figma).&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Tech Lead Discuss PRD and UI Mockup with engineers, analyze requirements and unveiling details, edge cases. Then engineering team writes a document outlining the system architecture, database changes, and API designs, key user metric gather plan, releases plan.&lt;/p&gt;

&lt;p&gt;It is shared with the wider engineering team for peer review to catch flaws early.&lt;br&gt;
Time allocation of this work referenced by SPIKE Ticket within sprint.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Output: RFC (Request for Comments) / TDD (Technical Design document)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Upon receiving feedback, passing reviews, Technical design is approved and proceed to&lt;/p&gt;

&lt;p&gt;Backlog Grooming: The PM and Engineering Lead break the PRD down into "tickets" (tasks) in a tool like Jira. Each ticket is assigned "Story Points" to estimate effort.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Flow: Step-by-Step
&lt;/h2&gt;

&lt;p&gt;Startups typically run on Scrum or Kanban frameworks, operating in 2-week "Sprints."&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;| Phase        | Key Activity                           | Output            |
|--------------|----------------------------------------|-------------------|
| Estimation   | Pointing session with developers       | Sprint Backlog    |
| Execution    | Coding, Code Reviews (PRs), CI/CD      | Feature Branch    |
| QA/UAT       | Automated testing &amp;amp; stakeholder review | Release Candidate |
| Launch       | Feature flags &amp;amp; phased rollout         | Live Feature      |

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Key Documents &amp;amp; Tools
&lt;/h2&gt;

&lt;p&gt;Modern startups favor "Asynchronous Documentation" writing things down so anyone can catch up without a meeting.&lt;/p&gt;

&lt;p&gt;Product Roadmap: A high-level timeline (usually quarterly) showing "Now, Next, Later."&lt;/p&gt;

&lt;p&gt;RACI Matrix: A chart defining who is Responsible, Accountable, Consulted, and Informed for the project.&lt;/p&gt;

&lt;p&gt;Service Level Agreements (SLAs): Documentation on expected uptime and performance for the new feature.&lt;/p&gt;

&lt;p&gt;Tech Stack: * Project Tracking: Linear, Jira, or Asana.&lt;/p&gt;

&lt;p&gt;Docs: Notion, Confluence, or GitHub Wiki.&lt;/p&gt;

&lt;p&gt;Design: Figma.&lt;/p&gt;

&lt;p&gt;Communication: Slack (integrated with GitHub/Jira).&lt;/p&gt;




&lt;h2&gt;
  
  
  Timelines
&lt;/h2&gt;

&lt;p&gt;While timelines vary by feature size, a standard "medium-sized" project (e.g., building a new dashboard) usually follows this cadence:&lt;/p&gt;

&lt;p&gt;Week 1-2 (Discovery): Research, PRD drafting, and stakeholder alignment.&lt;/p&gt;

&lt;p&gt;Week 3 (Technical Design): RFC/TDD writing, peer review, and Figma prototyping.&lt;/p&gt;

&lt;p&gt;Week 4-7 (Development): 2 or 3 Sprints of active coding. Includes daily "Stand-ups" (15-min syncs).&lt;/p&gt;

&lt;p&gt;Week 8 (Testing &amp;amp; Polish): Bug smashing and User Acceptance Testing (UAT).&lt;/p&gt;

&lt;p&gt;Week 9 (Deployment): Usually a "Dark Launch" (deploying code behind a toggle) followed by a full release.&lt;/p&gt;




&lt;p&gt;That concludes the overview process from requirement to production delivery, but its also crucial to have post-launch process&lt;/p&gt;

&lt;h2&gt;
  
  
  Product team
&lt;/h2&gt;

&lt;p&gt;needs to gather the user feedback, monitor analytics like Amplitude, Mixpanel, or Google Analytic to analyze the impact according to initial PRD plan.&lt;br&gt;
Tech team provides analytics and its metric setup and configurations beforehand.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tech team
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Observability &amp;amp; Monitoring&lt;/strong&gt; &lt;br&gt;
Developers watch dashboards (e.g., Datadog, New Relic, or Sentry) for a "spike" in error rates. If the new code causes the server to crash or slow down, they must hotfix it immediately.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Feature Flag Cleanup&lt;/strong&gt; &lt;br&gt;
Most startups use LaunchDarkly or Statsig to toggle features on. Once a feature is 100% rolled out and stable, the "tech debt" task is to go back into the code and remove the "if/else" logic for that toggle.&lt;/p&gt;

&lt;p&gt;"Nothing is more permanent than temporary solution" &lt;br&gt;
&lt;strong&gt;Addressing Technical Debt&lt;/strong&gt;&lt;br&gt;
Often, to meet a deadline, developers take "shortcuts." Post-launch is the time to go back and refactor that code to make it more maintainable. The team must create clear timeline when to refactor or completely ignore it, otherwise tech debt will be under radar forever and can hurt maintainability in long term.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Performance Tuning&lt;/strong&gt;&lt;br&gt;
Now that real user data is hitting the database, the Tech Lead checks if the queries are performing as expected or if they need to add new indexes to the database.&lt;/p&gt;




&lt;h2&gt;
  
  
  The "Post-Mortem" / Retrospective
&lt;/h2&gt;

&lt;p&gt;This is a formal meeting and document created 1–2 weeks after launch. It is the most important document for team growth.&lt;/p&gt;

&lt;p&gt;The Document Structure:&lt;/p&gt;

&lt;p&gt;What went well? (e.g., "The RFC process caught a major security flaw early.")&lt;/p&gt;

&lt;p&gt;What went wrong? (e.g., "The Figma designs were missing a mobile view, causing a 2-day delay.")&lt;/p&gt;

&lt;p&gt;Timeline Reality vs. Estimate: Did it take 3 sprints instead of 2? Why?&lt;/p&gt;

&lt;p&gt;Action Items: Concrete steps to prevent the same mistakes in the next project.&lt;/p&gt;

</description>
      <category>softwareengineering</category>
      <category>development</category>
    </item>
    <item>
      <title>I thought Vercel's backend was just like another backend...</title>
      <dc:creator>Software Jutsu</dc:creator>
      <pubDate>Sat, 10 Jan 2026 02:29:29 +0000</pubDate>
      <link>https://forem.com/softwarejutsu/i-thought-vercels-backend-was-just-like-another-backend-328f</link>
      <guid>https://forem.com/softwarejutsu/i-thought-vercels-backend-was-just-like-another-backend-328f</guid>
      <description>&lt;p&gt;Lesson learned about Vercel vs. Traditional Backend&lt;/p&gt;

&lt;p&gt;On my journey to learn Next.js in-depth through projects, i tried to architect my Next.js backend server like normal golang's backend (dependency injection). Turns out its not possible.&lt;/p&gt;

&lt;p&gt;I treat Vercel’s /api routes like a "mini Express server." This is a fundamental architectural error. While both run Node.js, their underlying infrastructure (Serverless vs. Long-Running) dictates completely different rules.&lt;br&gt;
Then i dig further to understand why service model like Vercel are different from backend in common...&lt;/p&gt;

&lt;p&gt;Other services that work similar are Netlify, Cloudflare Pages / Workers, AWS Amplify.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Process Lifecycle: Ephemeral vs. Persistent
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Traditional Backend (Long-Running)&lt;/strong&gt;&lt;br&gt;
The Concept: The process starts and stays alive until you manually stop it or it crashes.&lt;br&gt;
The "Global Root" is permanent. Memory is allocated once and remains available across thousands of different requests.&lt;/p&gt;

&lt;p&gt;Implication: You can rely on the server "remembering" things in its internal RAM for days or weeks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vercel (Serverless)&lt;/strong&gt;&lt;br&gt;
The Concept: The process is Ephemeral. It is "born" when a request arrives and "executed" (terminated or frozen) the millisecond the response is sent.&lt;br&gt;
The "Global Root" is destroyed frequently.&lt;/p&gt;

&lt;p&gt;Implication: Any internal state is wiped. You must treat every request as if the server just performed a "Cold Start."&lt;/p&gt;

&lt;h2&gt;
  
  
  2. State Management: The Global Variable Trap
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Traditional Backend (Long-Running)&lt;/strong&gt;&lt;br&gt;
Memory: Global variables are Shared. If &lt;strong&gt;User A&lt;/strong&gt; updates a global counter, &lt;strong&gt;User B&lt;/strong&gt; sees the updated value because they are hitting the same process.&lt;/p&gt;

&lt;p&gt;Garbage Collection: As long as the process lives, GC ignores global variables because they are "reachable." This allows for in-memory caching or simple counters.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vercel (Serverless)&lt;/strong&gt;&lt;br&gt;
Global variables are Isolated. If 10 users hit your API, Vercel may spin up 10 separate "Execution Environment" (lets call this instance).&lt;/p&gt;

&lt;p&gt;The Trap: User A updates a counter in Instance #1. User B hits Instance #2, which has a completely different Global Root where the counter is still 0.&lt;/p&gt;

&lt;p&gt;(This is bit more nuance to this,&lt;br&gt;
Global variable can still persist in its warm state, but reuse only happens sequentially, not simultaneously. if its Idle, it will return to its cold state, all global variable will be destroyed too.)&lt;/p&gt;

&lt;p&gt;You cannot use in memory data to keep state you want to persist on different request. You must use an external store like Redis or PostgreSQL.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Concurrency: Thread Pooling vs. Horizontal Scaling
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Traditional Backend (Long-Running)&lt;/strong&gt;&lt;br&gt;
Mechanism: One server handles multiple concurrent requests using a single thread with an Event Loop (Node.js). It manages a "pool" of connections.&lt;br&gt;
High traffic is handled by the server working harder. If it gets overwhelmed, requests queue up.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vercel (Serverless)&lt;/strong&gt;&lt;br&gt;
Mechanism: Vercel scales by Multiplication. If traffic spikes, it doesn't make one function work harder; it creates 1,000 copies of that function.&lt;br&gt;
This creates a "Connection Exhaustion" problem. If 1,000 functions spin up, they all try to open a new connection to your database at once, potentially crashing your DB. You must use a Connection Pooler (like Prisma Accelerate or Supabase Pooling).&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Execution Timing: Synchronous vs. Background Tasks
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Traditional Backend (Long-Running)&lt;/strong&gt;&lt;br&gt;
You can send a response to the user and continue running code in the background (e.g., res.send(); fireAndForgetEmail();).&lt;/p&gt;

&lt;p&gt;The process stays alive, so the email function finishes its work comfortably in the background.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vercel (Serverless)&lt;/strong&gt;&lt;br&gt;
The Flow: The moment res.send() is called, the runtime environment is paused or killed.&lt;/p&gt;

&lt;p&gt;The Disaster: If you try to run a background task after the response, Vercel will likely "cut the power" mid-execution. Your email might be half-sent or never sent at all.&lt;/p&gt;

&lt;p&gt;Every task must be finished before the response, or delegated to a queue service (like Upstash Workflow).&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Persistent Connections: WebSockets vs. HTTP
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Traditional Backend (Long-Running)&lt;/strong&gt;&lt;br&gt;
Connectivity: Supports Stateful connections. &lt;br&gt;
A client can keep a TCP socket open (WebSockets) for real-time chat or live updates. The server process is always there to "hold the other end of the string."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vercel (Serverless)&lt;/strong&gt;&lt;br&gt;
Connectivity: Supports Stateless HTTP requests only.&lt;/p&gt;

&lt;p&gt;Since the function dies after the response, it cannot "hold" a connection open. If you try to use socket.io, it will fail because the "server" disappears every few seconds.&lt;br&gt;
For real-time features, you must use a third-party "Realtime-as-a-Service" like Pusher or Ably.&lt;/p&gt;




&lt;p&gt;This article made with AI assistance, and note to myself.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>🔧 Typescript Generics - Practical Guide and examples</title>
      <dc:creator>Software Jutsu</dc:creator>
      <pubDate>Thu, 19 Jun 2025 08:01:27 +0000</pubDate>
      <link>https://forem.com/softwarejutsu/practical-guide-to-generics-in-typescript-7cc</link>
      <guid>https://forem.com/softwarejutsu/practical-guide-to-generics-in-typescript-7cc</guid>
      <description>&lt;p&gt;Generics, reminds me to early days of studying typescript, when i see those T, U, V characters inside &amp;lt; brackets &amp;gt; that scared the hell out of me and i try to avoid them. &lt;br&gt;
once i understand them, they are actually not that scary, they are powerful.&lt;/p&gt;

&lt;p&gt;I collected examples that will help you quickly understand &lt;strong&gt;why&lt;/strong&gt;, and &lt;strong&gt;how&lt;/strong&gt; to use &lt;strong&gt;generics&lt;/strong&gt;, without have to read through the complex documentation and confusing explanations. 😭&lt;/p&gt;
&lt;h1&gt;
  
  
  What are Generics?
&lt;/h1&gt;

&lt;p&gt;Generics let you pass a type as a parameter to functions, interfaces, or classes.&lt;/p&gt;

&lt;p&gt;Think of it as a function parameter, but for types.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;doSomething&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, T is a type placeholder. When you use the function, T gets replaced by the actual type you pass.&lt;/p&gt;

&lt;p&gt;T is just convention, you can actually name it anything you like,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;doSomething&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;TTypeBeingPassedHere&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;TTypeBeingPassedHere&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;TTypeBeingPassedHere&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To give distinct identifier, commonly its starts with T followed by the name, here is another example&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;doSomething&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;TInput&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;inputOne&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;TInput&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;TInput&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ... some logic here&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;doSomething&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// returns number&lt;/span&gt;
&lt;span class="nx"&gt;doSomething&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// returns string&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code defines the function must always return &lt;code&gt;TInput&lt;/code&gt;, and it passed by the  of the caller,&lt;br&gt;
in this case &lt;code&gt;TInput&lt;/code&gt; passed as &lt;code&gt;number&lt;/code&gt; hence it will return number&lt;/p&gt;

&lt;p&gt;🧐 Why Use Generics? &lt;br&gt;
Avoid using any (which removes type safety)&lt;br&gt;
Avoid code duplication&lt;br&gt;
Write reusable and type-safe utilities&lt;/p&gt;

&lt;p&gt;to easier understand how generic works and its benefits, take a look of more examples below.&lt;/p&gt;
&lt;h1&gt;
  
  
  Common use case scenarios
&lt;/h1&gt;


&lt;h2&gt;
  
  
  Reusing Logic Without Losing Types
&lt;/h2&gt;

&lt;p&gt;Scenario: You want to write a utility function that works with any type but still keeps the original type intact.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;wrapInArray&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;numberArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;wrapInArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;     &lt;span class="c1"&gt;// number[]&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;stringArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;wrapInArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hello&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// string[]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🧠 Why use generics?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you used any, you’d lose type safety.&lt;/li&gt;
&lt;li&gt;If you hardcoded string, you couldn’t reuse it for number.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Handling API Responses
&lt;/h2&gt;

&lt;p&gt;Scenario: You fetch data from different endpoints. All responses follow the same format: data + success. But the data can vary.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;ApiResponse&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;userResponse&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ApiResponse&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Alice&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;postsResponse&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ApiResponse&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;post 1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;post 2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🧠 Why use generics?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You avoid duplicating the structure. ApiResponse can be re-used for different response shape.&lt;/li&gt;
&lt;li&gt;You get full type safety no matter what data is.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Creating Flexible List Utilities
&lt;/h2&gt;

&lt;p&gt;Scenario: You want a function like getFirstItem, and you want it to work for any array type.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getFirstItem&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;[]):&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;firstName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getFirstItem&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Rick&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Morty&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt; &lt;span class="c1"&gt;// string&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;firstNumber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getFirstItem&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;     &lt;span class="c1"&gt;// number&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🧠 Why use generics?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Without generics, you’d either duplicate the function or use any&lt;a href="https://dev.tobad%20idea"&gt;&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Extending Built-in Types Safely
&lt;/h2&gt;

&lt;p&gt;Scenario: You want to write a function that only accepts objects that have a length, like strings or arrays — not numbers or booleans.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;logLength&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;logLength&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hello&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;     &lt;span class="c1"&gt;// valid&lt;/span&gt;
&lt;span class="nf"&gt;logLength&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;   &lt;span class="c1"&gt;// valid&lt;/span&gt;
&lt;span class="nf"&gt;logLength&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;         &lt;span class="c1"&gt;// ❌ Error: number doesn't have length&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🧠 Why use generics with extends?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Combined with use of Extends, you can selectively accepts types of Generics you allow, in this case logLength only accepts anything that compatible with &lt;code&gt;{ length: number}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;You define a flexible type that still enforces structure.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  React Hook That Works with Any Type
&lt;/h2&gt;

&lt;p&gt;Scenario: You want a useLocalStorage hook that works with any type of value — string, number, object, etc.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;useLocalStorage&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;initialValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setValue&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;json&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;json&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;initialValue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setValue&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🧠 Why use generics?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;So this hook works with boolean, string, { id: number }, or anything else, with full autocomplete and safety.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Generic Class for Storing Any Type
&lt;/h2&gt;

&lt;p&gt;Scenario: You want a class that stores data of any type.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Store&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="na"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

  &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;getAll&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;userStore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Store&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;userStore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Alice&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;numberStore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Store&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;numberStore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🧠 Why use generics?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One class works for both objects, strings, and numbers - without rewriting the logic.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;official reference &lt;a href="https://www.typescriptlang.org/docs/handbook/2/generics.html" rel="noopener noreferrer"&gt;https://www.typescriptlang.org/docs/handbook/2/generics.html&lt;/a&gt;&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>webdev</category>
      <category>react</category>
    </item>
    <item>
      <title>Understanding TypeScript’s Comments: @ts-ignore, @ts-expect-error, and Friends</title>
      <dc:creator>Software Jutsu</dc:creator>
      <pubDate>Sat, 14 Jun 2025 08:22:59 +0000</pubDate>
      <link>https://forem.com/softwarejutsu/understanding-typescripts-comments-ts-ignore-ts-expect-error-and-friends-38p9</link>
      <guid>https://forem.com/softwarejutsu/understanding-typescripts-comments-ts-ignore-ts-expect-error-and-friends-38p9</guid>
      <description>&lt;p&gt;When working with TypeScript, you've probably seen some strange-looking comments like // @ts-ignore or // @ts-expect-error. These are TypeScript directives, often called “magic comments” — and they can change how the compiler behaves for specific lines or files.&lt;br&gt;
what exactly is it? what are the difference?&lt;/p&gt;

&lt;p&gt;Let's walk through the 4 most important directives you should know.&lt;/p&gt;
&lt;h2&gt;
  
  
  1. // @ts-expect-error
&lt;/h2&gt;

&lt;p&gt;This directive tells TypeScript:&lt;/p&gt;

&lt;p&gt;“I expect the next line to throw a type error. If it doesn't, fail the build.”&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// @ts-expect-error
const name: number = "John"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the error is later fixed (intentionally or by accident), the compiler throws an error:&lt;/p&gt;

&lt;p&gt;Unused '@ts-expect-error' directive.&lt;/p&gt;

&lt;p&gt;✅ Why it's good:&lt;br&gt;
    • Enforces that you're suppressing an error on purpose.&lt;br&gt;
    • Helps with testing or gradually migrating code.&lt;/p&gt;

&lt;p&gt;🛠 Use when:&lt;br&gt;
    • You're writing a test that expects an error.&lt;br&gt;
    • You're temporarily keeping known type errors but want safety.&lt;/p&gt;
&lt;h2&gt;
  
  
  2. // @ts-ignore
&lt;/h2&gt;

&lt;p&gt;This tells TypeScript:&lt;/p&gt;

&lt;p&gt;“Ignore all errors on the next line. I know what I'm doing.”&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// @ts-ignore
const user: string = 123
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Unlike @ts-expect-error, this will never alert you even if the error is gone later. It's silent and dangerous if overused.&lt;/p&gt;

&lt;p&gt;⚠️ Why it's risky:&lt;br&gt;
    • Suppresses all type checking on that line.&lt;br&gt;
    • Can hide bugs and technical debt.&lt;/p&gt;

&lt;p&gt;🛠 Use only when:&lt;br&gt;
    • There's no other option.&lt;br&gt;
    • You're integrating with legacy code, third-party libs, or non-typed APIs.&lt;/p&gt;

&lt;p&gt;I would avoid this at all cost.&lt;/p&gt;
&lt;h2&gt;
  
  
  3. // @ts-check (for .js files)
&lt;/h2&gt;

&lt;p&gt;This enables TypeScript type-checking for plain JavaScript files.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// @ts-check

/**
 * @param {number} x
 * @returns {number}
 */
function square(x) {
  return x * x
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🔍 Why it's useful:&lt;br&gt;
    • Allows you to catch type bugs in JS without migrating to .ts.&lt;br&gt;
    • You can annotate with JSDoc for full type checking.&lt;/p&gt;

&lt;p&gt;🛠 Use when:&lt;br&gt;
    • Gradually migrating a JS codebase to TS.&lt;br&gt;
    • You want lightweight type safety in JS.&lt;/p&gt;
&lt;h2&gt;
  
  
  4. // @ts-nocheck
&lt;/h2&gt;

&lt;p&gt;Disables all TypeScript checking for a file even in .ts or .tsx.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// @ts-nocheck

const user = getUser()
user.doSomethingThatDoesNotExist()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;💀 Why it's dangerous:&lt;br&gt;
    • Completely disables the TypeScript compiler for that file.&lt;br&gt;
    • Silently ignores all type and syntax errors.&lt;/p&gt;

&lt;p&gt;🛠 Use only when:&lt;br&gt;
    • You're working with untyped legacy code.&lt;br&gt;
    • You're debugging or temporarily disabling TS during migration.&lt;/p&gt;



&lt;p&gt;Overall, my take:&lt;br&gt;
    • Prefer @ts-expect-error over @ts-ignore for long-term maintainability.&lt;br&gt;
    • Use ESLint rules like @typescript-eslint/ban-ts-comment to restrict or require justification for using these comments.&lt;br&gt;
    • In a real project, flag every @ts-ignore for later cleanup.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;| Directive          | Scope       | Description                                      | Safe? |
|-------------------|-------------|--------------------------------------------------|--------|
| `@ts-expect-error` | One line    | Expect a type error. Fails if no error.         | ✅     |
| `@ts-ignore`       | One line    | Ignore any TS error on the next line.           | ⚠️     |
| `@ts-check`        | Whole file  | Enable TS checking in JS files.                 | ✅     |
| `@ts-nocheck`      | Whole file  | Disable all TS checking.                        | ❌     |
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use them wisely to reduce friction, not to hide problems.&lt;/p&gt;

&lt;p&gt;This article is part of my personal note, as reminder of problems and learnings i encounter on my daily work. I did use AI to help build the article. &lt;br&gt;
If you interested, follow.&lt;/p&gt;

&lt;p&gt;Author: &lt;a class="mentioned-user" href="https://dev.to/rickvian"&gt;@rickvian&lt;/a&gt; &lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to Check existing SSH public key in Windows</title>
      <dc:creator>Software Jutsu</dc:creator>
      <pubDate>Sat, 14 Jun 2025 08:18:58 +0000</pubDate>
      <link>https://forem.com/softwarejutsu/short-how-to-check-existing-ssh-public-key-in-windows-43kb</link>
      <guid>https://forem.com/softwarejutsu/short-how-to-check-existing-ssh-public-key-in-windows-43kb</guid>
      <description>&lt;p&gt;To check your existing SSH public key in Windows, you can follow these steps:&lt;/p&gt;

&lt;p&gt;Check Existing SSH Public Key in Windows (PowerShell, for Bitbucket use)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Open PowerShell&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Navigate to your SSH key directory (replace YourUsername if needed):&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd $env:USERPROFILE\.ssh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Display your public key:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Get-Content id_rsa.pub

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Note: If id_rsa.pub does not exist, generate a new key:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssh-keygen
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
  </channel>
</rss>
