<?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>DEV Community: Siswoyo Siswoyo</title>
    <description>The latest articles on DEV Community by Siswoyo Siswoyo (@siswoyo).</description>
    <link>https://dev.to/siswoyo</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3383512%2F8cf08f72-65c5-45dd-a648-557d465fed7b.jpg</url>
      <title>DEV Community: Siswoyo Siswoyo</title>
      <link>https://dev.to/siswoyo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/siswoyo"/>
    <language>en</language>
    <item>
      <title>stress-ng vs sysbench</title>
      <dc:creator>Siswoyo Siswoyo</dc:creator>
      <pubDate>Wed, 07 Oct 2026 03:05:35 +0000</pubDate>
      <link>https://dev.to/siswoyo/stress-ng-vs-sysbench-2jli</link>
      <guid>https://dev.to/siswoyo/stress-ng-vs-sysbench-2jli</guid>
      <description>&lt;h1&gt;
  
  
  stress-ng vs sysbench
&lt;/h1&gt;

&lt;p&gt;A practical guide to two common Linux load-generation tools: what each one does, how they differ, and when to use them.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Overview
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;stress-ng&lt;/th&gt;
&lt;th&gt;sysbench&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Primary goal&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Stress testing and fault finding&lt;/td&gt;
&lt;td&gt;Benchmarking and performance measurement&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;One-line summary&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Designed to break things&lt;/td&gt;
&lt;td&gt;Designed to measure things&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  2. stress-ng
&lt;/h2&gt;

&lt;p&gt;stress-ng loads a system's hardware and kernel interfaces in many different ways. It is a much larger successor to the original &lt;code&gt;stress&lt;/code&gt; tool.&lt;/p&gt;

&lt;h3&gt;
  
  
  Core features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Large set of stressors&lt;/strong&gt;: 300+ built-in tests, each exercising a specific part of the system.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CPU stress&lt;/strong&gt;: Many compute methods (integer, floating point, matrix, FFT, bit operations, hashing) via &lt;code&gt;--cpu&lt;/code&gt; and &lt;code&gt;--cpu-method&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memory stress&lt;/strong&gt;: Virtual memory, cache, memory copy, &lt;code&gt;mmap&lt;/code&gt;, page faults, NUMA, via &lt;code&gt;--vm&lt;/code&gt;, &lt;code&gt;--cache&lt;/code&gt;, &lt;code&gt;--memcpy&lt;/code&gt;, &lt;code&gt;--mmap&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;I/O and filesystem stress&lt;/strong&gt;: Disk reads/writes, &lt;code&gt;fsync&lt;/code&gt;, file locking, directory operations, via &lt;code&gt;--hdd&lt;/code&gt;, &lt;code&gt;--io&lt;/code&gt;, &lt;code&gt;--dir&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kernel interface stress&lt;/strong&gt;: Syscalls, signals, pipes, sockets, semaphores, message queues, futexes, threads, context switches, scheduler.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Network stress&lt;/strong&gt;: Socket and protocol-level tests.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Device and driver stress&lt;/strong&gt;: &lt;code&gt;ioctl&lt;/code&gt;, &lt;code&gt;/dev&lt;/code&gt;, &lt;code&gt;/proc&lt;/code&gt; and &lt;code&gt;/sys&lt;/code&gt; interfaces.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Control and configuration
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Option&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;--cpu 4&lt;/code&gt; / &lt;code&gt;--cpu 0&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Number of workers (&lt;code&gt;0&lt;/code&gt; = all online CPUs)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;--timeout 60s&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Stop after a set time&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;--cpu-ops N&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Stop after N operations&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;--cpu-load 50&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Target a CPU utilization percentage&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;--class cpu&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Run a group of stressors (cpu, memory, io, scheduler, ...)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;--all&lt;/code&gt;, &lt;code&gt;--random&lt;/code&gt;, &lt;code&gt;--sequential&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Permutation modes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-x&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Exclude specific stressors&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Measurement and reporting
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Bogo ops&lt;/strong&gt;: A rough throughput measure, useful for same-machine comparison but not a formal benchmark.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Metrics&lt;/strong&gt;: &lt;code&gt;--metrics&lt;/code&gt; / &lt;code&gt;--metrics-brief&lt;/code&gt; for summaries; &lt;code&gt;--yaml&lt;/code&gt; or &lt;code&gt;--log-file&lt;/code&gt; to save results.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Thermal and perf data&lt;/strong&gt;: &lt;code&gt;--thermalstat&lt;/code&gt;, &lt;code&gt;--vmstat&lt;/code&gt;, &lt;code&gt;--perf&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verification&lt;/strong&gt;: &lt;code&gt;--verify&lt;/code&gt; checks that results are correct, helping catch hardware faults or memory errors.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Common uses
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Burn-in and stability testing of new hardware&lt;/li&gt;
&lt;li&gt;Checking cooling and thermal throttling&lt;/li&gt;
&lt;li&gt;Finding kernel bugs or race conditions&lt;/li&gt;
&lt;li&gt;Testing behavior under resource pressure (CPU, RAM, I/O)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Example commands
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Stress all CPUs for 60 seconds with a summary&lt;/span&gt;
stress-ng &lt;span class="nt"&gt;--cpu&lt;/span&gt; 0 &lt;span class="nt"&gt;--timeout&lt;/span&gt; 60s &lt;span class="nt"&gt;--metrics-brief&lt;/span&gt;

&lt;span class="c"&gt;# 4 CPU workers, 2 VM workers using 1GB each, 1 disk worker&lt;/span&gt;
stress-ng &lt;span class="nt"&gt;--cpu&lt;/span&gt; 4 &lt;span class="nt"&gt;--vm&lt;/span&gt; 2 &lt;span class="nt"&gt;--vm-bytes&lt;/span&gt; 1G &lt;span class="nt"&gt;--hdd&lt;/span&gt; 1 &lt;span class="nt"&gt;--timeout&lt;/span&gt; 120s &lt;span class="nt"&gt;--metrics-brief&lt;/span&gt;

&lt;span class="c"&gt;# Run every CPU-class stressor in turn&lt;/span&gt;
stress-ng &lt;span class="nt"&gt;--class&lt;/span&gt; cpu &lt;span class="nt"&gt;--sequential&lt;/span&gt; 0 &lt;span class="nt"&gt;--timeout&lt;/span&gt; 30s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Caution:&lt;/strong&gt; stress-ng can make a system unresponsive, overheat, or crash, and some stressors can fill disks or trigger the OOM killer. Use it on test machines or with sensible limits, not carelessly on production.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  3. sysbench
&lt;/h2&gt;

&lt;p&gt;sysbench is a scriptable benchmark tool that produces repeatable performance numbers for CPU, memory, disk, threads, and databases.&lt;/p&gt;

&lt;h3&gt;
  
  
  Core features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;CPU&lt;/strong&gt;: Prime number computation benchmark.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memory&lt;/strong&gt;: Read/write throughput tests.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;File I/O&lt;/strong&gt;: Sequential and random read/write tests.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Threads and mutex&lt;/strong&gt;: Scheduler and locking performance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database (OLTP)&lt;/strong&gt;: Workloads for MySQL and PostgreSQL.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lua scripting&lt;/strong&gt;: Write custom workloads.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Example commands
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# CPU benchmark&lt;/span&gt;
sysbench cpu &lt;span class="nt"&gt;--threads&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;4 &lt;span class="nt"&gt;--time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;30 run

&lt;span class="c"&gt;# Memory throughput&lt;/span&gt;
sysbench memory &lt;span class="nt"&gt;--threads&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;4 run

&lt;span class="c"&gt;# File I/O&lt;/span&gt;
sysbench fileio &lt;span class="nt"&gt;--file-total-size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;2G prepare
sysbench fileio &lt;span class="nt"&gt;--file-total-size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;2G &lt;span class="nt"&gt;--file-test-mode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;rndrw run
sysbench fileio &lt;span class="nt"&gt;--file-total-size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;2G cleanup
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  4. Key Differences
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;stress-ng&lt;/th&gt;
&lt;th&gt;sysbench&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Purpose&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Stress testing, fault finding&lt;/td&gt;
&lt;td&gt;Benchmarking, performance comparison&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Scope&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Very broad (300+ stressors)&lt;/td&gt;
&lt;td&gt;Narrow: CPU, memory, file I/O, threads, database&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Output&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Bogo ops (rough, same-machine only)&lt;/td&gt;
&lt;td&gt;Events/sec, latency percentiles, MiB/sec&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Database testing&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;Strong (OLTP for MySQL/PostgreSQL)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Correctness checking&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Yes (&lt;code&gt;--verify&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;No, measures speed only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Extensibility&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Modify the C source&lt;/td&gt;
&lt;td&gt;Lua scripts&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  5. Which One Should You Use?
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Goal&lt;/th&gt;
&lt;th&gt;Recommended tool&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Burn-in, thermal, or stability testing&lt;/td&gt;
&lt;td&gt;stress-ng&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Kernel bug hunting&lt;/td&gt;
&lt;td&gt;stress-ng&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Comparing two servers or VM sizes&lt;/td&gt;
&lt;td&gt;sysbench&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Measuring the effect of tuning changes&lt;/td&gt;
&lt;td&gt;sysbench&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Database server performance&lt;/td&gt;
&lt;td&gt;sysbench&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Using them together
&lt;/h3&gt;

&lt;p&gt;The two tools complement each other:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Run &lt;strong&gt;stress-ng&lt;/strong&gt; to confirm the system stays stable under heavy load.&lt;/li&gt;
&lt;li&gt;Run &lt;strong&gt;sysbench&lt;/strong&gt; to record how fast the system actually is.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  6. Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;stress-ng&lt;/strong&gt; answers: &lt;em&gt;"Does this system survive heavy load?"&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;sysbench&lt;/strong&gt; answers: &lt;em&gt;"How fast is this system?"&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;References:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://sysbench.org/" rel="noopener noreferrer"&gt;https://sysbench.org/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/ColinIanKing/stress-ng" rel="noopener noreferrer"&gt;https://github.com/ColinIanKing/stress-ng&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>testing</category>
    </item>
    <item>
      <title>YAGNI: You Aren't Gonna Need It</title>
      <dc:creator>Siswoyo Siswoyo</dc:creator>
      <pubDate>Tue, 29 Sep 2026 06:33:02 +0000</pubDate>
      <link>https://dev.to/siswoyo/yagni-you-arent-gonna-need-it-54i</link>
      <guid>https://dev.to/siswoyo/yagni-you-arent-gonna-need-it-54i</guid>
      <description>&lt;h1&gt;
  
  
  YAGNI: You Aren't Gonna Need It
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Don't add functionality until there's a real, present use case for it.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What Is YAGNI?
&lt;/h2&gt;

&lt;p&gt;YAGNI stands for &lt;strong&gt;"You Aren't Gonna Need It."&lt;/strong&gt; It comes from Extreme Programming (XP) and is a core idea in agile development. The principle says developers should implement things only when they are actually needed, not when they merely &lt;em&gt;foresee&lt;/em&gt; needing them.&lt;/p&gt;

&lt;p&gt;It's easy to think, &lt;em&gt;"We might need this later, so let's build it now."&lt;/em&gt; YAGNI pushes back on that habit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Speculative Features Are a Problem
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Problem&lt;/th&gt;
&lt;th&gt;Explanation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Wasted time&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;You spend effort building something that may never be used.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Extra complexity&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;More code means more bugs, more tests, and more to understand.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Wrong guesses&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Future requirements rarely match what you predicted.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Maintenance burden&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Unused code still has to be updated, refactored, and reviewed.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Slower delivery&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Time spent on "maybe" features delays real, valuable ones.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  A Simple Example
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ❌ Violating YAGNI
&lt;/h3&gt;

&lt;p&gt;Requirement: &lt;em&gt;"Save a user's name to a file."&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DataStorage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;storage_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;file&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;storage_type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;storage_type&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;storage_type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;file&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_save_to_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;storage_type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;database&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_save_to_database&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;# Nobody asked for this
&lt;/span&gt;        &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;storage_type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cloud&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_save_to_cloud&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;      &lt;span class="c1"&gt;# Or this
&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;_save_to_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="bp"&gt;...&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;_save_to_database&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="bp"&gt;...&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;_save_to_cloud&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="bp"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ✅ Following YAGNI
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;save_user_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user.txt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;w&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If a database is required later, you can refactor &lt;strong&gt;then&lt;/strong&gt;, with real requirements in hand.&lt;/p&gt;

&lt;h2&gt;
  
  
  When Should You Add Something?
&lt;/h2&gt;

&lt;p&gt;Ask yourself these questions before building:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Is there a real user story or requirement today?&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Is someone actually blocked without this?&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Would adding it later be dramatically more expensive?&lt;/strong&gt; (Usually it isn't.)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If the answers are &lt;em&gt;no&lt;/em&gt;, &lt;em&gt;no&lt;/em&gt;, and &lt;em&gt;no&lt;/em&gt;, don't build it yet.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common YAGNI Violations
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Adding configuration options nobody has asked for&lt;/li&gt;
&lt;li&gt;Creating abstract base classes with a single implementation&lt;/li&gt;
&lt;li&gt;Building plugin systems for an app with one use case&lt;/li&gt;
&lt;li&gt;Adding database columns "just in case"&lt;/li&gt;
&lt;li&gt;Supporting multiple languages or currencies before you have international users&lt;/li&gt;
&lt;li&gt;Over-engineering APIs with parameters that are never used&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What YAGNI Is &lt;em&gt;Not&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;YAGNI is often misunderstood. It does &lt;strong&gt;not&lt;/strong&gt; mean:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;❌ Writing sloppy or unstructured code&lt;/li&gt;
&lt;li&gt;❌ Ignoring good design and architecture&lt;/li&gt;
&lt;li&gt;❌ Skipping tests, security, or error handling&lt;/li&gt;
&lt;li&gt;❌ Refusing to plan at all&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The principle applies to &lt;strong&gt;features and speculative generality&lt;/strong&gt;, not to code quality. In fact, YAGNI works best alongside:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Automated tests&lt;/strong&gt;, which make later changes safe&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Refactoring&lt;/strong&gt;, so you can adapt when needs appear&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Continuous integration&lt;/strong&gt;, for fast feedback&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Simple design&lt;/strong&gt; (see also: KISS)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  YAGNI vs. Related Principles
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Principle&lt;/th&gt;
&lt;th&gt;Focus&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;YAGNI&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Don't build features before they're needed.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;KISS&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Keep solutions simple.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;DRY&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Don't repeat yourself; avoid duplicated knowledge.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Premature Optimization&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Don't optimize before you've measured a real problem.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Caveat: When Anticipating the Future Is Reasonable
&lt;/h2&gt;

&lt;p&gt;There are exceptions where planning ahead makes sense:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Public APIs or database schemas&lt;/strong&gt; that are very hard to change later&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security-critical foundations&lt;/strong&gt;, such as authentication design&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Regulatory or contractual requirements&lt;/strong&gt; that are known and certain&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The key word is &lt;em&gt;known&lt;/em&gt;. If the need is a certainty rather than a guess, it's a real requirement, not speculation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Build for &lt;strong&gt;today's requirements&lt;/strong&gt;, not imagined future ones.&lt;/li&gt;
&lt;li&gt;Every line of code has a &lt;strong&gt;cost&lt;/strong&gt;: writing, testing, and maintaining it.&lt;/li&gt;
&lt;li&gt;Simple code is &lt;strong&gt;easier to change&lt;/strong&gt; when real needs emerge.&lt;/li&gt;
&lt;li&gt;Combine YAGNI with &lt;strong&gt;tests and refactoring&lt;/strong&gt; so you can evolve safely.&lt;/li&gt;
&lt;li&gt;Delaying a decision until you have more information is often the &lt;strong&gt;smartest choice&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Always implement things when you actually need them, never when you just foresee that you need them."&lt;/em&gt;&lt;br&gt;
— Ron Jeffries, co-founder of Extreme Programming&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Reference: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://martinfowler.com/bliki/Yagni.html" rel="noopener noreferrer"&gt;https://martinfowler.com/bliki/Yagni.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>agile</category>
      <category>programming</category>
    </item>
    <item>
      <title>Architecture Comparison: NGINX Only vs NGINX + API Gateway</title>
      <dc:creator>Siswoyo Siswoyo</dc:creator>
      <pubDate>Fri, 08 May 2026 06:54:51 +0000</pubDate>
      <link>https://dev.to/siswoyo/architecture-comparison-nginx-only-vs-nginx-api-gateway-1j8d</link>
      <guid>https://dev.to/siswoyo/architecture-comparison-nginx-only-vs-nginx-api-gateway-1j8d</guid>
      <description>&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;This document compares two common microservice architecture patterns to help you decide which approach best fits your use case.&lt;/p&gt;




&lt;h2&gt;
  
  
  Architecture Diagrams
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Option 1 — NGINX Only
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Client
   ↓
NGINX
   ↓
Microservices
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Option 2 — NGINX + API Gateway
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Client
   ↓
NGINX
   ↓
API Gateway
   ↓
Microservices
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Comparison by Category
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Complexity
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;NGINX Only&lt;/th&gt;
&lt;th&gt;NGINX + API Gateway&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Infrastructure&lt;/td&gt;
&lt;td&gt;Simpler&lt;/td&gt;
&lt;td&gt;More complex&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Number of services&lt;/td&gt;
&lt;td&gt;Fewer&lt;/td&gt;
&lt;td&gt;Additional gateway service&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Configuration&lt;/td&gt;
&lt;td&gt;Easier&lt;/td&gt;
&lt;td&gt;More layers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Debugging&lt;/td&gt;
&lt;td&gt;Easier&lt;/td&gt;
&lt;td&gt;Harder&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Maintenance&lt;/td&gt;
&lt;td&gt;Lower&lt;/td&gt;
&lt;td&gt;Higher&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Winner: ✅ NGINX Only&lt;/strong&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  2. Performance
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;NGINX Only&lt;/th&gt;
&lt;th&gt;NGINX + API Gateway&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Request hops&lt;/td&gt;
&lt;td&gt;Fewer&lt;/td&gt;
&lt;td&gt;More&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Latency&lt;/td&gt;
&lt;td&gt;Lower&lt;/td&gt;
&lt;td&gt;Slightly higher&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Resource usage&lt;/td&gt;
&lt;td&gt;Lower&lt;/td&gt;
&lt;td&gt;Higher&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Throughput&lt;/td&gt;
&lt;td&gt;Better&lt;/td&gt;
&lt;td&gt;Slightly lower&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Winner: ✅ NGINX Only&lt;/strong&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  3. Routing
&lt;/h3&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;NGINX Only&lt;/th&gt;
&lt;th&gt;API Gateway&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Path routing&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Load balancing&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Header-based routing&lt;/td&gt;
&lt;td&gt;Limited&lt;/td&gt;
&lt;td&gt;Better&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dynamic routing&lt;/td&gt;
&lt;td&gt;Limited&lt;/td&gt;
&lt;td&gt;Better&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Service discovery&lt;/td&gt;
&lt;td&gt;Manual&lt;/td&gt;
&lt;td&gt;Better&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Canary deployment&lt;/td&gt;
&lt;td&gt;Harder&lt;/td&gt;
&lt;td&gt;Easier&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Winner: ✅ API Gateway&lt;/strong&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  4. Security
&lt;/h3&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;NGINX Only&lt;/th&gt;
&lt;th&gt;API Gateway&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;SSL termination&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;Usually via NGINX&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;JWT validation&lt;/td&gt;
&lt;td&gt;In every service&lt;/td&gt;
&lt;td&gt;Centralized&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RBAC&lt;/td&gt;
&lt;td&gt;In services&lt;/td&gt;
&lt;td&gt;Easier centralized&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OAuth2 integration&lt;/td&gt;
&lt;td&gt;Harder&lt;/td&gt;
&lt;td&gt;Easier&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API key management&lt;/td&gt;
&lt;td&gt;Limited&lt;/td&gt;
&lt;td&gt;Better&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Threat protection&lt;/td&gt;
&lt;td&gt;Limited&lt;/td&gt;
&lt;td&gt;Better&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Winner: ✅ API Gateway&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; If your services already validate JWT, security is already strong — the advantage of an API Gateway in this area may be less significant.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  5. Scalability
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;NGINX Only&lt;/th&gt;
&lt;th&gt;NGINX + API Gateway&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Horizontal scaling&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Docker scaling&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Kubernetes readiness&lt;/td&gt;
&lt;td&gt;Moderate&lt;/td&gt;
&lt;td&gt;Better&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Service mesh integration&lt;/td&gt;
&lt;td&gt;Harder&lt;/td&gt;
&lt;td&gt;Easier&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dynamic service registration&lt;/td&gt;
&lt;td&gt;Manual&lt;/td&gt;
&lt;td&gt;Easier&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Winner: ✅ API Gateway (large scale)&lt;/strong&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  6. Observability &amp;amp; Monitoring
&lt;/h3&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;NGINX Only&lt;/th&gt;
&lt;th&gt;API Gateway&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Access logging&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Distributed tracing&lt;/td&gt;
&lt;td&gt;Harder&lt;/td&gt;
&lt;td&gt;Easier&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Request correlation&lt;/td&gt;
&lt;td&gt;Manual&lt;/td&gt;
&lt;td&gt;Better&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Centralized metrics&lt;/td&gt;
&lt;td&gt;Limited&lt;/td&gt;
&lt;td&gt;Better&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OpenTelemetry integration&lt;/td&gt;
&lt;td&gt;Harder&lt;/td&gt;
&lt;td&gt;Easier&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Winner: ✅ API Gateway&lt;/strong&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  7. Rate Limiting
&lt;/h3&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;NGINX Only&lt;/th&gt;
&lt;th&gt;API Gateway&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Basic rate limit&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Per-user limit&lt;/td&gt;
&lt;td&gt;Harder&lt;/td&gt;
&lt;td&gt;Easier&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Per-role limit&lt;/td&gt;
&lt;td&gt;Harder&lt;/td&gt;
&lt;td&gt;Easier&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API quota&lt;/td&gt;
&lt;td&gt;Limited&lt;/td&gt;
&lt;td&gt;Better&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Winner: ✅ API Gateway&lt;/strong&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  8. Development Speed
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;NGINX Only&lt;/th&gt;
&lt;th&gt;NGINX + API Gateway&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Faster setup&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Easier onboarding&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Easier deployment&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Less code&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Winner: ✅ NGINX Only&lt;/strong&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  9. Cost &amp;amp; Resource Usage
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;NGINX Only&lt;/th&gt;
&lt;th&gt;NGINX + API Gateway&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;RAM usage&lt;/td&gt;
&lt;td&gt;Lower&lt;/td&gt;
&lt;td&gt;Higher&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CPU usage&lt;/td&gt;
&lt;td&gt;Lower&lt;/td&gt;
&lt;td&gt;Higher&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Container count&lt;/td&gt;
&lt;td&gt;Lower&lt;/td&gt;
&lt;td&gt;Higher&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Operational cost&lt;/td&gt;
&lt;td&gt;Lower&lt;/td&gt;
&lt;td&gt;Higher&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Winner: ✅ NGINX Only&lt;/strong&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  10. Enterprise Features
&lt;/h3&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;NGINX Only&lt;/th&gt;
&lt;th&gt;API Gateway&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Circuit breaker&lt;/td&gt;
&lt;td&gt;Limited&lt;/td&gt;
&lt;td&gt;Better&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API aggregation&lt;/td&gt;
&lt;td&gt;Harder&lt;/td&gt;
&lt;td&gt;Easier&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Request transformation&lt;/td&gt;
&lt;td&gt;Limited&lt;/td&gt;
&lt;td&gt;Better&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GraphQL federation&lt;/td&gt;
&lt;td&gt;Harder&lt;/td&gt;
&lt;td&gt;Easier&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Multi-tenant gateway policies&lt;/td&gt;
&lt;td&gt;Harder&lt;/td&gt;
&lt;td&gt;Easier&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Backend-for-Frontend (BFF)&lt;/td&gt;
&lt;td&gt;Harder&lt;/td&gt;
&lt;td&gt;Easier&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Winner: ✅ API Gateway&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Summary Scorecard
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;th&gt;Winner&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Complexity&lt;/td&gt;
&lt;td&gt;✅ NGINX Only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Performance&lt;/td&gt;
&lt;td&gt;✅ NGINX Only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Routing&lt;/td&gt;
&lt;td&gt;✅ API Gateway&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Security&lt;/td&gt;
&lt;td&gt;✅ API Gateway&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scalability&lt;/td&gt;
&lt;td&gt;✅ API Gateway&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Observability &amp;amp; Monitoring&lt;/td&gt;
&lt;td&gt;✅ API Gateway&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rate Limiting&lt;/td&gt;
&lt;td&gt;✅ API Gateway&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Development Speed&lt;/td&gt;
&lt;td&gt;✅ NGINX Only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cost &amp;amp; Resource Usage&lt;/td&gt;
&lt;td&gt;✅ NGINX Only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Enterprise Features&lt;/td&gt;
&lt;td&gt;✅ API Gateway&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;NGINX Only wins: 4/10&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;API Gateway wins: 6/10&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Recommendation
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Choose NGINX Only&lt;/strong&gt; if you prioritize simplicity, lower resource usage, fast setup, and your current JWT validation per-service is already sufficient for your security needs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Choose NGINX + API Gateway&lt;/strong&gt; if you need advanced routing, centralized security, better observability, rate limiting per user/role, and enterprise-grade features — especially at large scale or in Kubernetes environments.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>architecture</category>
    </item>
    <item>
      <title>Apache JMeter – Overview and Practical Guide</title>
      <dc:creator>Siswoyo Siswoyo</dc:creator>
      <pubDate>Wed, 17 Dec 2025 07:15:33 +0000</pubDate>
      <link>https://dev.to/siswoyo/apache-jmeter-overview-and-practical-guide-4h7l</link>
      <guid>https://dev.to/siswoyo/apache-jmeter-overview-and-practical-guide-4h7l</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbk901s4vn4rnknffdzz7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbk901s4vn4rnknffdzz7.png" alt=" " width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Apache JMeter?
&lt;/h2&gt;

&lt;p&gt;Apache JMeter is an open‑source performance and load testing tool written in Java. It is widely used to test the performance, scalability, and reliability of applications such as web apps, APIs, microservices, databases, and messaging systems. JMeter simulates real user traffic by generating concurrent requests and measuring how the system behaves under different loads.&lt;/p&gt;

&lt;p&gt;Originally designed for web applications, JMeter has evolved into a full‑featured testing platform supporting REST, SOAP, JDBC, FTP, TCP, JMS, Kafka (via plugins), and more.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Use JMeter?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Open Source &amp;amp; Free&lt;/strong&gt; – No licensing cost&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cross‑Platform&lt;/strong&gt; – Runs on Windows, macOS, and Linux&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Highly Extensible&lt;/strong&gt; – Large ecosystem of plugins&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalable Testing&lt;/strong&gt; – Supports distributed (master–slave) testing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CI/CD Friendly&lt;/strong&gt; – Can be run in headless (CLI) mode&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Common Use Cases
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Load testing REST and SOAP APIs&lt;/li&gt;
&lt;li&gt;Stress testing e‑commerce applications&lt;/li&gt;
&lt;li&gt;Performance testing microservices&lt;/li&gt;
&lt;li&gt;Database performance testing (JDBC)&lt;/li&gt;
&lt;li&gt;Message queue testing (RabbitMQ, Kafka, JMS)&lt;/li&gt;
&lt;li&gt;Regression performance testing before release&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Core JMeter Concepts
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Test Plan
&lt;/h3&gt;

&lt;p&gt;A &lt;strong&gt;Test Plan&lt;/strong&gt; is the top‑level container that defines:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What to test&lt;/li&gt;
&lt;li&gt;How many users to simulate&lt;/li&gt;
&lt;li&gt;How requests are executed&lt;/li&gt;
&lt;li&gt;What data to collect&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Thread Group (Virtual Users)
&lt;/h3&gt;

&lt;p&gt;A &lt;strong&gt;Thread Group&lt;/strong&gt; represents virtual users (threads).&lt;br&gt;
Key parameters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Number of Threads (Users)&lt;/strong&gt; – Total concurrent users&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ramp‑Up Period (seconds)&lt;/strong&gt; – Time to start all users&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Loop Count&lt;/strong&gt; – How many times each user runs the test&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Users: 100&lt;/li&gt;
&lt;li&gt;Ramp‑up: 10 seconds → ~10 users start per second&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  3. Sampler
&lt;/h3&gt;

&lt;p&gt;A &lt;strong&gt;Sampler&lt;/strong&gt; defines the actual request sent to the server.&lt;br&gt;
Common samplers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HTTP Request (REST, Web)&lt;/li&gt;
&lt;li&gt;JDBC Request (Database)&lt;/li&gt;
&lt;li&gt;JMS Publisher / Subscriber&lt;/li&gt;
&lt;li&gt;TCP Sampler&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  4. Config Elements
&lt;/h3&gt;

&lt;p&gt;Used to define shared configuration:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HTTP Request Defaults&lt;/li&gt;
&lt;li&gt;HTTP Header Manager&lt;/li&gt;
&lt;li&gt;CSV Data Set Config (for test data)&lt;/li&gt;
&lt;li&gt;User Defined Variables&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  5. Timers
&lt;/h3&gt;

&lt;p&gt;Timers control delays between requests:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Constant Timer&lt;/li&gt;
&lt;li&gt;Uniform Random Timer&lt;/li&gt;
&lt;li&gt;Gaussian Random Timer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Used to simulate real user behavior.&lt;/p&gt;
&lt;h3&gt;
  
  
  6. Assertions
&lt;/h3&gt;

&lt;p&gt;Assertions validate responses:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Response code (200, 201, etc.)&lt;/li&gt;
&lt;li&gt;Response body contains expected text&lt;/li&gt;
&lt;li&gt;JSON / XPath assertions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Assertions help ensure correctness, not just speed.&lt;/p&gt;
&lt;h3&gt;
  
  
  7. Listeners
&lt;/h3&gt;

&lt;p&gt;Listeners collect and display test results:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;View Results Tree (debugging)&lt;/li&gt;
&lt;li&gt;Summary Report&lt;/li&gt;
&lt;li&gt;Aggregate Report&lt;/li&gt;
&lt;li&gt;Response Time Graph&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;⚠️ Avoid heavy listeners during large tests.&lt;/p&gt;


&lt;h2&gt;
  
  
  Key Performance Metrics in JMeter
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Load Time&lt;/strong&gt; – Total time to complete the request&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Connect Time&lt;/strong&gt; – Time to establish connection&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Latency&lt;/strong&gt; – Time until first byte is received&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Throughput&lt;/strong&gt; – Requests per second&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Error Rate&lt;/strong&gt; – Percentage of failed requests&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Response Size&lt;/strong&gt; – Bytes sent/received&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These metrics help identify bottlenecks.&lt;/p&gt;


&lt;h2&gt;
  
  
  Example: E‑Commerce Load Test Scenario
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;User browses product list&lt;/li&gt;
&lt;li&gt;User views product detail&lt;/li&gt;
&lt;li&gt;User adds item to cart&lt;/li&gt;
&lt;li&gt;User checks out&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Thread Group Strategy&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;10 users (baseline)&lt;/li&gt;
&lt;li&gt;50 users (normal load)&lt;/li&gt;
&lt;li&gt;100 users (peak load)&lt;/li&gt;
&lt;li&gt;500 users (stress test)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Assertions&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HTTP 200 on browse&lt;/li&gt;
&lt;li&gt;Cart response contains product ID&lt;/li&gt;
&lt;li&gt;Checkout returns order ID&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Running JMeter Tests
&lt;/h2&gt;
&lt;h3&gt;
  
  
  GUI Mode (Development Only)
&lt;/h3&gt;

&lt;p&gt;Used for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creating test plans&lt;/li&gt;
&lt;li&gt;Debugging requests&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Non‑GUI Mode (Production / CI)
&lt;/h3&gt;

&lt;p&gt;Recommended for load testing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;jmeter &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="nt"&gt;-t&lt;/span&gt; test.jmx &lt;span class="nt"&gt;-l&lt;/span&gt; result.jtl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lower memory usage&lt;/li&gt;
&lt;li&gt;Faster execution&lt;/li&gt;
&lt;li&gt;CI/CD compatible&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa9l7khc2ktq648ic6bu9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa9l7khc2ktq648ic6bu9.png" alt=" " width="800" height="418"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Best Practices
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;strong&gt;CSV files&lt;/strong&gt; for test data (users, tokens)&lt;/li&gt;
&lt;li&gt;Disable heavy listeners for large loads&lt;/li&gt;
&lt;li&gt;Run JMeter in &lt;strong&gt;non‑GUI mode&lt;/strong&gt; for real tests&lt;/li&gt;
&lt;li&gt;Monitor server resources (CPU, memory, DB)&lt;/li&gt;
&lt;li&gt;Start with small load, increase gradually&lt;/li&gt;
&lt;li&gt;Separate functional testing from performance testing&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Limitations of JMeter
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Not a browser (no real JavaScript rendering)&lt;/li&gt;
&lt;li&gt;High load requires tuning or distributed setup&lt;/li&gt;
&lt;li&gt;GUI mode consumes high memory&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For frontend performance, combine with tools like browser‑based testing.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Apache JMeter is a powerful and flexible tool for performance testing. When used correctly, it helps teams understand system limits, prevent production failures, and improve application reliability. It is especially effective for API‑based systems, microservices, and backend performance validation.&lt;/p&gt;

&lt;p&gt;Reference: &lt;a href="https://jmeter.apache.org/" rel="noopener noreferrer"&gt;https://jmeter.apache.org/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>testing</category>
      <category>programming</category>
      <category>backenddevelopment</category>
    </item>
    <item>
      <title>Install ISPConfig with Nginx Webserver on Ubuntu 22.04</title>
      <dc:creator>Siswoyo Siswoyo</dc:creator>
      <pubDate>Tue, 04 Nov 2025 04:08:03 +0000</pubDate>
      <link>https://dev.to/siswoyo/install-ispconfig-with-nginx-webserver-on-ubuntu-2204-492f</link>
      <guid>https://dev.to/siswoyo/install-ispconfig-with-nginx-webserver-on-ubuntu-2204-492f</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;ISPConfig is a very popular open‑source hosting control panel that lets&lt;br&gt;
you manage websites, email accounts, DNS records, FTP, and more. Using&lt;br&gt;
Nginx as the web server is typically more performant than Apache for&lt;br&gt;
many scenarios (especially static content, reverse‑proxying etc). This&lt;br&gt;
guide shows how to install ISPConfig 3 + Nginx on Ubuntu 22.04, starting&lt;br&gt;
from a fresh system.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Important&lt;/strong&gt;: This setup assumes a fresh, clean OS install with&lt;br&gt;
minimal/no prior custom configuration. Doing this on a server with&lt;br&gt;
many existing services/configs may lead to conflicts.&lt;br&gt;
(&lt;a href="https://www.howtoforge.com/ispconfig-autoinstall-debian-ubuntu/" rel="noopener noreferrer"&gt;howtoforge.com&lt;/a&gt;)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before you begin: - A server running Ubuntu 22.04 (64‑bit) with internet&lt;br&gt;
access. - A hostname set correctly (see below). - A public IP address,&lt;br&gt;
reachable, DNS configured (so your hostname resolves). - Ports such as&lt;br&gt;
HTTP (80), HTTPS (443), and the ISPConfig panel port (8080) must not be&lt;br&gt;
blocked. - You'll be logged in as root (or using sudo). - The OS should&lt;br&gt;
be essentially "clean" (no major services already installed or&lt;br&gt;
customised that the auto‑installer will clobber).&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 1: Log in to the server
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Step 2: Configure the hostname and hosts file
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Pick a fully qualified domain name (FQDN) for your server such as&lt;br&gt;
&lt;code&gt;server1.example.com&lt;/code&gt;. Do &lt;strong&gt;not&lt;/strong&gt; just use &lt;code&gt;example.com&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Edit &lt;code&gt;/etc/hosts&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight shell"&gt;&lt;code&gt;nano /etc/hosts
&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;and ensure you have a line like:&lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;127.0.1.1   server1.example.com   server1
&lt;/code&gt;&lt;/pre&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Edit &lt;code&gt;/etc/hostname&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight shell"&gt;&lt;code&gt;nano /etc/hostname
&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;Put only the short hostname (e.g., &lt;code&gt;server1&lt;/code&gt;).&lt;/p&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Reboot the server:&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight shell"&gt;&lt;code&gt;systemctl reboot
&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;After reboot, verify:&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;hostname
hostname&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;




&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Ensure your DNS provider has an A (and/or AAAA) record for&lt;br&gt;&lt;br&gt;
&lt;code&gt;server1.example.com&lt;/code&gt; pointing to your server's public IP.&lt;/p&gt;&lt;/li&gt;

&lt;/ol&gt;

&lt;h2&gt;
  
  
  Step 3: Update the system
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;apt update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt upgrade &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 4: Run the auto‑installer for ISPConfig with Nginx
&lt;/h2&gt;

&lt;p&gt;Now is the key part: installing ISPConfig and choosing Nginx as the web&lt;br&gt;
server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;wget &lt;span class="nt"&gt;-O&lt;/span&gt; - https://get.ispconfig.org | sh &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nt"&gt;--use-nginx&lt;/span&gt; &lt;span class="nt"&gt;--use-ftp-ports&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;40110-40210 &lt;span class="nt"&gt;--unattended-upgrades&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What the arguments mean
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;--use-nginx&lt;/code&gt; → use Nginx instead of Apache.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;--use-ftp-ports=40110-40210&lt;/code&gt; → set passive FTP port range for
Pure‑FTPd.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;--unattended-upgrades&lt;/code&gt; → enables automatic updates/upgrades.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  After installation completes
&lt;/h3&gt;

&lt;p&gt;You'll see the generated passwords, e.g.:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[INFO] Your ISPConfig admin password is: &amp;lt;password&amp;gt;
[INFO] Your MySQL root password is: &amp;lt;password&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Ensure you record these.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Setting up the firewall
&lt;/h2&gt;

&lt;p&gt;Allow necessary ports through UFW or within ISPConfig UI → System →&lt;br&gt;
Firewall.&lt;/p&gt;

&lt;p&gt;TCP ports:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;20,21,22,25,80,443,40110:40210,110,143,465,587,993,995,53,8080,8081
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;UDP:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;53
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Step 6: Finalizing
&lt;/h2&gt;

&lt;p&gt;Log into ISPConfig panel:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://server1.example.com:8080
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Login user: &lt;code&gt;admin&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgh1ets4rwrfmp2xv2bj4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgh1ets4rwrfmp2xv2bj4.png" alt=" " width="800" height="457"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 7: Adding Your Website
&lt;/h2&gt;

&lt;p&gt;Once you are inside the ISPConfig panel, you can start adding new&lt;br&gt;
websites under &lt;strong&gt;Sites → Add new site&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Before you add a website: - Ensure your domain name (e.g.,&lt;br&gt;
&lt;code&gt;example.com&lt;/code&gt;) is &lt;strong&gt;already pointing&lt;/strong&gt; to your server's public IP&lt;br&gt;
address. - You can check your DNS propagation and record setup using&lt;br&gt;
&lt;a href="https://dnschecker.org/" rel="noopener noreferrer"&gt;https://dnschecker.org/&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If your domain is not yet propagated or pointing to the correct IP, the&lt;br&gt;
site might not load correctly.&lt;/p&gt;
&lt;h3&gt;
  
  
  Steps to add a site:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt; Go to &lt;strong&gt;Sites → Add new website&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt; Enter your domain name (e.g., &lt;code&gt;example.com&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt; Choose the IP address of your server (you can leave it as * if you want ISPConfig to use all available IPs).&lt;/li&gt;
&lt;li&gt; Set PHP version, SSL (Let's Encrypt), and other options.&lt;/li&gt;
&lt;li&gt; Save your configuration.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;After saving, ISPConfig will create the Nginx virtual host configuration&lt;br&gt;
automatically.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 8: Advanced options
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;--channel=&amp;lt;stable|dev&amp;gt;&lt;/code&gt; → choose branch&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;--lang=en|de&lt;/code&gt; → choose language&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;--use-php=7.4,8.1&lt;/code&gt; → install specific PHP versions&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;--no-mail&lt;/code&gt; → skip mail server&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;--no-dns&lt;/code&gt; → skip DNS server&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;--debug&lt;/code&gt; → detailed log in
&lt;code&gt;/tmp/ispconfig-ai/var/log/ispconfig.log&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example for minimal install:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;wget &lt;span class="nt"&gt;-O&lt;/span&gt; - https://get.ispconfig.org | sh &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nt"&gt;--use-nginx&lt;/span&gt; &lt;span class="nt"&gt;--no-dns&lt;/span&gt; &lt;span class="nt"&gt;--no-mail&lt;/span&gt; &lt;span class="nt"&gt;--use-ftp-ports&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;40110-40210 &lt;span class="nt"&gt;--unattended-upgrades&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 9: Troubleshooting
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  Rerun with &lt;code&gt;--debug&lt;/code&gt; if installation fails.&lt;/li&gt;
&lt;li&gt;  Check &lt;code&gt;/tmp/ispconfig-ai/var/log/ispconfig.log&lt;/code&gt; for details.&lt;/li&gt;
&lt;li&gt;  Ensure fresh OS install to avoid config conflicts.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;You can now manage websites, email, DNS, databases, and FTP through&lt;br&gt;
ISPConfig 3 with Nginx on Ubuntu 22.04.&lt;/p&gt;

&lt;p&gt;Before adding sites, make sure your domain and public IP setup are&lt;br&gt;
verified using &lt;a href="https://dnschecker.org/" rel="noopener noreferrer"&gt;DNSChecker.org&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Reference:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.ispconfig.org/blog/ispconfig-installation-on-ubuntu-22-04/" rel="noopener noreferrer"&gt;https://www.ispconfig.org/blog/ispconfig-installation-on-ubuntu-22-04/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.howtoforge.com/ispconfig-autoinstall-debian-ubuntu/" rel="noopener noreferrer"&gt;https://www.howtoforge.com/ispconfig-autoinstall-debian-ubuntu/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>nginx</category>
      <category>ubuntu</category>
    </item>
    <item>
      <title>The `tree` Command in Ubuntu</title>
      <dc:creator>Siswoyo Siswoyo</dc:creator>
      <pubDate>Fri, 10 Oct 2025 08:30:57 +0000</pubDate>
      <link>https://dev.to/siswoyo/the-tree-command-in-ubuntu-42g8</link>
      <guid>https://dev.to/siswoyo/the-tree-command-in-ubuntu-42g8</guid>
      <description>&lt;h2&gt;
  
  
  📌 Introduction
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;tree&lt;/code&gt; command in Ubuntu is a powerful utility that displays the contents of directories in a &lt;strong&gt;tree-like structure&lt;/strong&gt;. Instead of listing files and directories in a flat list (like &lt;code&gt;ls&lt;/code&gt; does), it visually represents the hierarchy of directories, making it easier to understand the structure of a file system.&lt;/p&gt;

&lt;p&gt;This is especially useful for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Viewing project structures
&lt;/li&gt;
&lt;li&gt;Exploring configuration files
&lt;/li&gt;
&lt;li&gt;Understanding nested directories at a glance
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  📥 Installation
&lt;/h2&gt;

&lt;p&gt;By default, &lt;code&gt;tree&lt;/code&gt; may not be installed on Ubuntu. You can install it using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;tree &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To confirm installation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;tree &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  📂 Basic Usage
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Display current directory structure&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   tree
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Show full path of files and directories&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   tree &lt;span class="nt"&gt;-f&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Limit depth of directory tree&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   tree &lt;span class="nt"&gt;-L&lt;/span&gt; 2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(This shows only two levels deep.)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Show hidden files (dotfiles)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   tree &lt;span class="nt"&gt;-a&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;5. Print size of files&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   tree &lt;span class="nt"&gt;-s&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🎯 Common Options
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Option&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-a&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show all files including hidden ones&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-d&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;List directories only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-L n&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Limit depth of directory tree to &lt;code&gt;n&lt;/code&gt; levels&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-f&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Print full path for each file&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-s&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show file size in bytes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-h&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show file size in human-readable format&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;--du&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show cumulative directory sizes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-P&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;List only files matching a pattern&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-I&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Exclude files matching a pattern&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  🔍 Examples
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Display only directories up to 3 levels&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   tree &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;-L&lt;/span&gt; 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Show file sizes in human-readable format&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   tree &lt;span class="nt"&gt;-h&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Exclude specific directories (e.g., &lt;code&gt;.git&lt;/code&gt;)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   tree &lt;span class="nt"&gt;-I&lt;/span&gt; &lt;span class="s2"&gt;".git"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4. Display project structure&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   tree &lt;span class="nt"&gt;-L&lt;/span&gt; 2 &lt;span class="nt"&gt;-I&lt;/span&gt; &lt;span class="s2"&gt;"node_modules"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  📑 Example Output
&lt;/h2&gt;

&lt;p&gt;If you run &lt;code&gt;tree -L 2&lt;/code&gt; inside a project folder, you may get:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.
├── README.md
├── package.json
├── public
│   ├── index.html
│   └── favicon.ico
└── src
    ├── App.js
    ├── index.js
    └── components
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  ✅ Conclusion
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;tree&lt;/code&gt; command in Ubuntu is an essential tool for visualizing directory structures. With its various options, it allows developers, system administrators, and everyday users to quickly understand and navigate complex file systems.&lt;/p&gt;

&lt;p&gt;Reference: &lt;a href="https://manpages.ubuntu.com/manpages/jammy/man1/tree.1.html" rel="noopener noreferrer"&gt;https://manpages.ubuntu.com/manpages/jammy/man1/tree.1.html&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ubuntu</category>
    </item>
    <item>
      <title>Control Your Android on PC with Vysor</title>
      <dc:creator>Siswoyo Siswoyo</dc:creator>
      <pubDate>Wed, 10 Sep 2025 05:03:50 +0000</pubDate>
      <link>https://dev.to/siswoyo/control-your-android-on-pc-with-vysor-h07</link>
      <guid>https://dev.to/siswoyo/control-your-android-on-pc-with-vysor-h07</guid>
      <description>&lt;p&gt;Managing your Android device directly from your PC can greatly improve productivity, especially if you’re multitasking between your phone and computer. &lt;strong&gt;Vysor&lt;/strong&gt; is a powerful tool that lets you mirror and control your Android device from your Windows, macOS, Linux, or even Chrome browser.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Vysor?
&lt;/h2&gt;

&lt;p&gt;Vysor is a screen mirroring application developed by Koushik Dutta. It allows you to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;View your Android screen on your PC.&lt;/li&gt;
&lt;li&gt;Control your phone using your keyboard and mouse.&lt;/li&gt;
&lt;li&gt;Take screenshots and record your screen.&lt;/li&gt;
&lt;li&gt;Drag and drop files between your PC and Android device (Pro feature).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s especially useful for developers, customer support agents, or anyone who wants to interact with their phone without constantly switching devices.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Simple Setup&lt;/strong&gt; – Install the app on both your PC and Android device and connect via USB or Wi-Fi.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cross-Platform Support&lt;/strong&gt; – Works on Windows, macOS, Linux, and even Chrome.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keyboard &amp;amp; Mouse Control&lt;/strong&gt; – Type messages, play games, and navigate apps seamlessly.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;File Sharing&lt;/strong&gt; – Drag and drop files (Pro version).
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Screen Recording&lt;/strong&gt; – Record your Android screen directly from your PC.
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to Use Vysor
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Install Vysor
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Download and install Vysor on your PC from the official website: &lt;a href="https://www.vysor.io" rel="noopener noreferrer"&gt;https://www.vysor.io&lt;/a&gt;.
&lt;/li&gt;
&lt;li&gt;Install the &lt;strong&gt;Vysor app&lt;/strong&gt; from the Google Play Store on your Android device.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnyr7tmlsyhral5eaxgsg.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnyr7tmlsyhral5eaxgsg.jpeg" alt=" " width="561" height="1280"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Install ADB Drivers (Windows Users)
&lt;/h3&gt;

&lt;p&gt;To let your PC communicate with your Android phone, you need &lt;strong&gt;ADB (Android Debug Bridge) drivers&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Download the &lt;strong&gt;Universal ADB Driver&lt;/strong&gt;: &lt;a href="https://adb.clockworkmod.com" rel="noopener noreferrer"&gt;https://adb.clockworkmod.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Run the installer and follow the on-screen instructions.
&lt;/li&gt;
&lt;li&gt;Once installed, reconnect your Android device via USB.
&lt;/li&gt;
&lt;li&gt;Your PC should now recognize the phone when using Vysor.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frb0yi7bz9761zprpcdt4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frb0yi7bz9761zprpcdt4.png" alt=" " width="505" height="422"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;💡 &lt;strong&gt;Note for Mac/Linux users:&lt;/strong&gt; You don’t need to install extra drivers; ADB works out of the box.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Enable USB Debugging
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;On your Android device, go to &lt;strong&gt;Settings &amp;gt; About Phone &amp;gt; Tap “Build Number” 7 times&lt;/strong&gt; to enable Developer Options.
&lt;/li&gt;
&lt;li&gt;Go to &lt;strong&gt;Settings &amp;gt; Developer Options &amp;gt; Enable USB Debugging&lt;/strong&gt;.
&lt;/li&gt;
&lt;li&gt;Confirm the USB Debugging prompt when connecting your device to the PC.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp50skcfbplyqcw75qcae.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp50skcfbplyqcw75qcae.png" alt=" " width="336" height="830"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Connect Your Device
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Plug your Android device into your PC using a USB cable (Wi-Fi connection available in the Pro version).
&lt;/li&gt;
&lt;li&gt;Open Vysor on your PC, and your device should appear in the list.
&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;View&lt;/strong&gt; to start mirroring your Android screen.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;PC&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdfbfaaxlpdfwegs90v8e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdfbfaaxlpdfwegs90v8e.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Android&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgz1ualesc9ciwjvdrlt7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgz1ualesc9ciwjvdrlt7.png" alt=" " width="335" height="833"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Control Your Device
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use your keyboard to type messages.
&lt;/li&gt;
&lt;li&gt;Navigate apps with your mouse.
&lt;/li&gt;
&lt;li&gt;Enjoy seamless control without constantly switching between devices.
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Free vs Pro
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Free version&lt;/strong&gt;: Includes screen mirroring and basic controls with ads.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pro version&lt;/strong&gt;: Removes ads, adds Wi-Fi connectivity, full-screen mode, drag-and-drop, and HD quality.
&lt;/li&gt;
&lt;li&gt;You can check the latest pricing and subscription options here: &lt;a href="https://www.vysor.io/#pricing" rel="noopener noreferrer"&gt;Vysor Pricing&lt;/a&gt; – around &lt;strong&gt;$2.50/mo&lt;/strong&gt;, &lt;strong&gt;$10/yr&lt;/strong&gt;, or &lt;strong&gt;$40 lifetime&lt;/strong&gt; as listed on their site.
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Benefits of Using Vysor
&lt;/h2&gt;

&lt;p&gt;✅ Boosts productivity for developers and office users.&lt;br&gt;
✅ Easy for tech support to guide customers remotely.&lt;br&gt;
✅ Great for presentations and demos.&lt;br&gt;
✅ Makes mobile gaming easier on a larger screen.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.vysor.io" rel="noopener noreferrer"&gt;Vysor Official Website&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/koush/vysor.io" rel="noopener noreferrer"&gt;Vysor GitHub Repository&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;👉 With &lt;strong&gt;Vysor + ADB drivers&lt;/strong&gt;, you can fully control your Android from your PC with ease. Perfect for work, support, or entertainment.&lt;/p&gt;

</description>
      <category>android</category>
      <category>developers</category>
    </item>
    <item>
      <title>Homelab: A Complete Overview</title>
      <dc:creator>Siswoyo Siswoyo</dc:creator>
      <pubDate>Tue, 02 Sep 2025 16:33:01 +0000</pubDate>
      <link>https://dev.to/siswoyo/homelab-a-complete-overview-4098</link>
      <guid>https://dev.to/siswoyo/homelab-a-complete-overview-4098</guid>
      <description>&lt;h2&gt;
  
  
  📌 What is a Homelab?
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;homelab&lt;/strong&gt; is a personal environment where you experiment with technology, servers, and networking outside of production systems. It’s commonly used by IT enthusiasts, developers, and system administrators to &lt;strong&gt;learn, test, and self-host services&lt;/strong&gt; at home.  &lt;/p&gt;

&lt;p&gt;Homelabs can range from a simple single-PC setup to a rack of enterprise-grade servers.&lt;/p&gt;




&lt;h2&gt;
  
  
  🎯 Why Build a Homelab?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Learning &amp;amp; Experimentation&lt;/strong&gt;
Practice new technologies like Docker, Kubernetes, virtualization, and networking.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Skill Development&lt;/strong&gt;
Gain hands-on experience for IT certifications and real-world problem-solving.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Self-Hosting&lt;/strong&gt;
Run your own cloud services such as Nextcloud, media servers, VPN, or password managers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automation Practice&lt;/strong&gt;
Experiment with tools like Ansible, Terraform, and CI/CD pipelines.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost Savings&lt;/strong&gt;
Repurpose old hardware instead of relying on expensive cloud providers.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🛠️ Common Homelab Components
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Hardware
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Old desktop PCs or laptops&lt;/li&gt;
&lt;li&gt;Mini PCs (Intel NUC, Raspberry Pi)&lt;/li&gt;
&lt;li&gt;Used enterprise servers (Dell PowerEdge, HP ProLiant)&lt;/li&gt;
&lt;li&gt;Network equipment (routers, switches, firewalls)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Virtualization &amp;amp; Containers
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Proxmox&lt;/strong&gt; – open-source virtualization&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;VMware ESXi&lt;/strong&gt; – enterprise-grade hypervisor&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Docker&lt;/strong&gt; – container platform for apps&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kubernetes / K3s&lt;/strong&gt; – container orchestration&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Networking
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;VLANs, VPNs, firewalls&lt;/li&gt;
&lt;li&gt;Pi-hole for DNS-level ad blocking&lt;/li&gt;
&lt;li&gt;pfSense or OPNsense for routing &amp;amp; security&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. Services to Run
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Media servers&lt;/strong&gt;: Plex, Jellyfin&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;File storage&lt;/strong&gt;: Nextcloud, Syncthing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DevOps tools&lt;/strong&gt;: GitLab, Jenkins&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monitoring&lt;/strong&gt;: Grafana, Prometheus&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Home automation&lt;/strong&gt;: Home Assistant&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧑‍💻 Example Homelab Setup
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Server&lt;/strong&gt;: Old Dell PowerEdge with 32GB RAM&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Virtualization&lt;/strong&gt;: Proxmox for managing VMs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Containers&lt;/strong&gt;: Docker running Nextcloud, Plex, Grafana&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Network&lt;/strong&gt;: pfSense firewall + Pi-hole DNS&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Storage&lt;/strong&gt;: RAID-configured NAS for backups&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ⚡ Tips for Building Your Homelab
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Start small&lt;/strong&gt; – repurpose an old laptop or Raspberry Pi.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Document everything&lt;/strong&gt; – keep notes on configs and setups.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use automation&lt;/strong&gt; – learn Ansible/Terraform to manage infrastructure.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backup frequently&lt;/strong&gt; – test disaster recovery.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keep it secure&lt;/strong&gt; – use strong passwords, VPN, and firewalls.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  📚 Resources to Get Started
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.reddit.com/r/homelab/" rel="noopener noreferrer"&gt;r/homelab on Reddit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pve.proxmox.com/wiki/Main_Page" rel="noopener noreferrer"&gt;Proxmox Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/awesome-selfhosted/awesome-selfhosted" rel="noopener noreferrer"&gt;Self-Hosted on GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.linuxserver.io/" rel="noopener noreferrer"&gt;Linux Server IO&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;✅ A homelab is not just a playground—it’s a &lt;strong&gt;personal cloud&lt;/strong&gt;, &lt;strong&gt;learning lab&lt;/strong&gt;, and &lt;strong&gt;automation hub&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>docker</category>
      <category>developers</category>
      <category>ansible</category>
      <category>jenkins</category>
    </item>
    <item>
      <title>Transaction Numbers in a System</title>
      <dc:creator>Siswoyo Siswoyo</dc:creator>
      <pubDate>Mon, 01 Sep 2025 18:11:43 +0000</pubDate>
      <link>https://dev.to/siswoyo/transaction-numbers-in-a-system-20n8</link>
      <guid>https://dev.to/siswoyo/transaction-numbers-in-a-system-20n8</guid>
      <description>&lt;p&gt;When designing a system that handles financial or operational transactions (e.g., orders, invoices, payments, shipments), one of the most important considerations is how &lt;strong&gt;transaction numbers&lt;/strong&gt; are generated and managed.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Why Transaction Numbers Are Important
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Uniqueness&lt;/strong&gt; → Every transaction must be identifiable without confusion.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Traceability&lt;/strong&gt; → Makes it easy to track and audit transactions.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Integration&lt;/strong&gt; → When multiple services or systems are involved, transaction numbers must remain consistent.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;User Reference&lt;/strong&gt; → Customers and staff often need a simple reference number for communication.
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Common Approaches to Transaction Numbers
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Auto-Increment Serial (Sequential Numbers)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Example: &lt;code&gt;TRX-000001&lt;/code&gt;, &lt;code&gt;TRX-000002&lt;/code&gt;, &lt;code&gt;TRX-000003&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pros&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Simple and human-friendly.
&lt;/li&gt;
&lt;li&gt;Easy to track the count of transactions.
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Cons&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Hard to merge across multiple systems (risk of duplicate numbers).
&lt;/li&gt;
&lt;li&gt;Predictable numbers can expose business volume.
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. UUID (Universally Unique Identifier)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Example: &lt;code&gt;d290f1ee-6c54-4b01-90e6-d701748f0851&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pros&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Guaranteed uniqueness across systems and services.
&lt;/li&gt;
&lt;li&gt;No collision issues when merging data.
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Cons&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Not user-friendly.
&lt;/li&gt;
&lt;li&gt;Longer to store and index in databases.
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Hybrid Format (Prefix + Date + Sequence / UUID)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Example: &lt;code&gt;INV-20250819-0012&lt;/code&gt; or &lt;code&gt;PAY-2025-08-19-XYZ123&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pros&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Human-readable with context (date, type).
&lt;/li&gt;
&lt;li&gt;Sequence helps ordering within a day.
&lt;/li&gt;
&lt;li&gt;Can still incorporate randomness or UUID for uniqueness.
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Cons&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Slightly more complex to implement.
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Recommended Practice
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;For &lt;strong&gt;internal system identifiers&lt;/strong&gt;: use &lt;strong&gt;UUIDs&lt;/strong&gt; to ensure uniqueness, especially in distributed or microservice architectures.
&lt;/li&gt;
&lt;li&gt;For &lt;strong&gt;user-facing transaction numbers&lt;/strong&gt;: generate a &lt;strong&gt;readable sequence with prefixes and dates&lt;/strong&gt; (e.g., &lt;code&gt;ORD-20250819-0456&lt;/code&gt;).
&lt;/li&gt;
&lt;li&gt;Store both values:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Primary Key / Internal ID&lt;/strong&gt; → UUID
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Public Transaction Number&lt;/strong&gt; → Sequential or Hybrid format
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Example: Dual Identifier Approach
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Example Value&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;transaction_id&lt;/code&gt; (UUID)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;a9c3b5f4-2e4b-4ef9-a2af...&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Internal system reference&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;transaction_no&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ORD-20250819-0456&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;User-facing, easy to reference&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This way, the system remains &lt;strong&gt;scalable, merge-friendly, and user-friendly&lt;/strong&gt;.  &lt;/p&gt;

&lt;h2&gt;
  
  
  SQL Schema Example
&lt;/h2&gt;

&lt;p&gt;Below is a PostgreSQL example showing how to implement this approach:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;transactions&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;transaction_id&lt;/span&gt; &lt;span class="n"&gt;UUID&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="n"&gt;gen_random_uuid&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="c1"&gt;-- Internal unique ID&lt;/span&gt;
    &lt;span class="n"&gt;transaction_no&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;UNIQUE&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;                &lt;span class="c1"&gt;-- Public transaction number&lt;/span&gt;
    &lt;span class="n"&gt;transaction_type&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&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="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;                     &lt;span class="c1"&gt;-- e.g. ORDER, PAYMENT, INVOICE&lt;/span&gt;
    &lt;span class="n"&gt;transaction_date&lt;/span&gt; &lt;span class="nb"&gt;TIMESTAMP&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="n"&gt;NOW&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="n"&gt;customer_id&lt;/span&gt; &lt;span class="n"&gt;UUID&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;amount&lt;/span&gt; &lt;span class="nb"&gt;NUMERIC&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;12&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="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&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="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="s1"&gt;'PENDING'&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;-- Example: Insert with a generated transaction number&lt;/span&gt;
&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;transactions&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;transaction_no&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;transaction_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;customer_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;VALUES&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;CONCAT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'ORD-'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TO_CHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NOW&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="s1"&gt;'YYYYMMDD'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s1"&gt;'-'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;LPAD&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nextval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'transaction_seq'&lt;/span&gt;&lt;span class="p"&gt;)::&lt;/span&gt;&lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'0'&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="s1"&gt;'ORDER'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'550e8400-e29b-41d4-a716-446655440000'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="mi"&gt;150000&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;-- Sequence for daily increment&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="n"&gt;SEQUENCE&lt;/span&gt; &lt;span class="n"&gt;transaction_seq&lt;/span&gt; &lt;span class="k"&gt;START&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;-- Example: Insert with a generated transaction number&lt;/span&gt;
&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;transactions&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;transaction_no&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;transaction_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;customer_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;VALUES&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;CONCAT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'ORD-'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TO_CHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NOW&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="s1"&gt;'YYYYMMDD'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s1"&gt;'-'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;LPAD&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nextval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'transaction_seq'&lt;/span&gt;&lt;span class="p"&gt;)::&lt;/span&gt;&lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'0'&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="s1"&gt;'ORDER'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'550e8400-e29b-41d4-a716-446655440000'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="mi"&gt;150000&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Relationships with Other Tables
&lt;/h2&gt;

&lt;p&gt;When designing related tables, always use transaction_id (UUID) as the foreign key.&lt;br&gt;
Each related table should also have its own unique reference number (payment_no, shipment_no).&lt;/p&gt;

&lt;h2&gt;
  
  
  Payments Table
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;payments&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;payment_id&lt;/span&gt; &lt;span class="n"&gt;UUID&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="n"&gt;gen_random_uuid&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="c1"&gt;-- Internal unique ID&lt;/span&gt;
    &lt;span class="n"&gt;payment_no&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;UNIQUE&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;                &lt;span class="c1"&gt;-- Public payment number&lt;/span&gt;
    &lt;span class="n"&gt;transaction_id&lt;/span&gt; &lt;span class="n"&gt;UUID&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt; &lt;span class="k"&gt;REFERENCES&lt;/span&gt; &lt;span class="n"&gt;transactions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;transaction_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="k"&gt;DELETE&lt;/span&gt; &lt;span class="k"&gt;CASCADE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;payment_date&lt;/span&gt; &lt;span class="nb"&gt;TIMESTAMP&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="n"&gt;NOW&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="n"&gt;payment_method&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;amount&lt;/span&gt; &lt;span class="nb"&gt;NUMERIC&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;12&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="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;-- Sequence for payments&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="n"&gt;SEQUENCE&lt;/span&gt; &lt;span class="n"&gt;payment_seq&lt;/span&gt; &lt;span class="k"&gt;START&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;-- Example insert&lt;/span&gt;
&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;payments&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payment_no&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;transaction_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;payment_method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;VALUES&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;CONCAT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'PAY-'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TO_CHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NOW&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="s1"&gt;'YYYYMMDD'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s1"&gt;'-'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;LPAD&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nextval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'payment_seq'&lt;/span&gt;&lt;span class="p"&gt;)::&lt;/span&gt;&lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'0'&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="s1"&gt;'a9c3b5f4-2e4b-4ef9-a2af-123456789abc'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'CREDIT_CARD'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="mi"&gt;150000&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Shipments Table
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;shipments&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;shipment_id&lt;/span&gt; &lt;span class="n"&gt;UUID&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="n"&gt;gen_random_uuid&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="c1"&gt;-- Internal unique ID&lt;/span&gt;
    &lt;span class="n"&gt;shipment_no&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;UNIQUE&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;                &lt;span class="c1"&gt;-- Public shipment number&lt;/span&gt;
    &lt;span class="n"&gt;transaction_id&lt;/span&gt; &lt;span class="n"&gt;UUID&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt; &lt;span class="k"&gt;REFERENCES&lt;/span&gt; &lt;span class="n"&gt;transactions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;transaction_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="k"&gt;DELETE&lt;/span&gt; &lt;span class="k"&gt;CASCADE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;courier&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;tracking_no&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&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="n"&gt;shipped_date&lt;/span&gt; &lt;span class="nb"&gt;TIMESTAMP&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;-- Sequence for shipments&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="n"&gt;SEQUENCE&lt;/span&gt; &lt;span class="n"&gt;shipment_seq&lt;/span&gt; &lt;span class="k"&gt;START&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;-- Example insert&lt;/span&gt;
&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;shipments&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;shipment_no&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;transaction_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;courier&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tracking_no&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;shipped_date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;VALUES&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;CONCAT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'SHP-'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TO_CHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NOW&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="s1"&gt;'YYYYMMDD'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s1"&gt;'-'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;LPAD&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nextval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'shipment_seq'&lt;/span&gt;&lt;span class="p"&gt;)::&lt;/span&gt;&lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'0'&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="s1"&gt;'a9c3b5f4-2e4b-4ef9-a2af-123456789abc'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'DHL'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'DHL123456789'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;NOW&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;h2&gt;
  
  
  Why Use UUID for Relations but Public Numbers for Reference?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;UUID (transaction_id, payment_id, shipment_id) → Used for database relations, stable and permanent.&lt;/li&gt;
&lt;li&gt;Public numbers (transaction_no, payment_no, shipment_no) → Used for communication with users, human-friendly, and can include business context (prefix, date, sequence).&lt;/li&gt;
&lt;li&gt;This ensures data integrity inside the system while providing clear references outside the system.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>systemdesign</category>
      <category>systems</category>
      <category>sql</category>
    </item>
    <item>
      <title>How to Create a Bootable USB Windows 10 Using Rufus</title>
      <dc:creator>Siswoyo Siswoyo</dc:creator>
      <pubDate>Wed, 27 Aug 2025 16:44:36 +0000</pubDate>
      <link>https://dev.to/siswoyo/how-to-create-a-bootable-usb-windows-10-using-rufus-1876</link>
      <guid>https://dev.to/siswoyo/how-to-create-a-bootable-usb-windows-10-using-rufus-1876</guid>
      <description>&lt;p&gt;Creating a bootable USB drive is one of the easiest and most reliable ways to install or reinstall Windows 10. With the help of &lt;strong&gt;Rufus&lt;/strong&gt;, a lightweight and free utility, you can prepare a USB stick to install Windows quickly.&lt;/p&gt;




&lt;h2&gt;
  
  
  ✅ What You Need
&lt;/h2&gt;

&lt;p&gt;Before starting, make sure you have the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A USB flash drive (at least &lt;strong&gt;8 GB&lt;/strong&gt; in size).&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;Windows 10 ISO file&lt;/strong&gt; (you can download it from the &lt;a href="https://www.microsoft.com/software-download/windows10" rel="noopener noreferrer"&gt;Microsoft website&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;The latest version of &lt;strong&gt;Rufus&lt;/strong&gt; (&lt;a href="https://rufus.ie/" rel="noopener noreferrer"&gt;download here&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🔧 Steps to Create Bootable USB with Rufus
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Download and Install Rufus
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Visit the &lt;a href="https://rufus.ie/" rel="noopener noreferrer"&gt;Rufus official website&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Download the latest version (portable, no installation required).&lt;/li&gt;
&lt;li&gt;Open the program by double-clicking &lt;strong&gt;Rufus.exe&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  2. Insert Your USB Drive
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Plug your USB flash drive into your computer.&lt;/li&gt;
&lt;li&gt;Rufus will automatically detect it under &lt;strong&gt;Device&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;⚠️ &lt;strong&gt;Note:&lt;/strong&gt; All data on the USB will be erased. Backup your important files first.&lt;/p&gt;




&lt;h3&gt;
  
  
  3. Select Windows 10 ISO File
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Under &lt;strong&gt;Boot selection&lt;/strong&gt;, click &lt;strong&gt;SELECT&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Browse and choose the Windows 10 ISO file you downloaded.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  4. Configure Partition Scheme
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Partition scheme:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Choose &lt;strong&gt;MBR&lt;/strong&gt; if installing on BIOS/Legacy systems.&lt;/li&gt;
&lt;li&gt;Choose &lt;strong&gt;GPT&lt;/strong&gt; if installing on UEFI systems.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;File system:&lt;/strong&gt; Leave as &lt;strong&gt;NTFS&lt;/strong&gt; (default).&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Cluster size:&lt;/strong&gt; Leave as default.&lt;/li&gt;

&lt;/ul&gt;




&lt;h3&gt;
  
  
  5. Start Creating Bootable USB
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Once settings are ready, click &lt;strong&gt;START&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Rufus may prompt to download additional files—accept if needed.&lt;/li&gt;
&lt;li&gt;A warning will appear that all data on the USB will be destroyed. Click &lt;strong&gt;OK&lt;/strong&gt; to proceed.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  6. Wait for Completion
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Rufus will format the USB and copy all Windows installation files.&lt;/li&gt;
&lt;li&gt;The process may take several minutes depending on USB speed.&lt;/li&gt;
&lt;li&gt;When the status bar turns &lt;strong&gt;green&lt;/strong&gt; and says &lt;em&gt;READY&lt;/em&gt;, your bootable USB is done.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnsq4q2hjy57klq4w314n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnsq4q2hjy57klq4w314n.png" alt=" " width="582" height="777"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 How to Use the Bootable USB
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Insert the USB drive into the target computer.&lt;/li&gt;
&lt;li&gt;Restart the computer and enter the &lt;strong&gt;boot menu&lt;/strong&gt; (usually by pressing &lt;strong&gt;F2, F12, ESC, or DEL&lt;/strong&gt;, depending on manufacturer).&lt;/li&gt;
&lt;li&gt;Select your USB drive as the boot device.&lt;/li&gt;
&lt;li&gt;Follow the on-screen instructions to install Windows 10.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  🎯 Conclusion
&lt;/h2&gt;

&lt;p&gt;Using Rufus makes creating a bootable USB for Windows 10 simple and fast. With just a few steps—selecting your USB, choosing the ISO, and starting the process—you’ll be ready to install or repair Windows 10 on any computer.&lt;/p&gt;

</description>
      <category>microsoft</category>
    </item>
    <item>
      <title>🎂 Happy Belated Birthday, Linux! 🐧💻</title>
      <dc:creator>Siswoyo Siswoyo</dc:creator>
      <pubDate>Tue, 26 Aug 2025 13:20:30 +0000</pubDate>
      <link>https://dev.to/siswoyo/happy-belated-birthday-linux-17o0</link>
      <guid>https://dev.to/siswoyo/happy-belated-birthday-linux-17o0</guid>
      <description>&lt;p&gt;On &lt;strong&gt;25 August 1991&lt;/strong&gt;, a young Finnish computer science student named &lt;strong&gt;Linus Torvalds&lt;/strong&gt; posted a short message on the MINIX newsgroup. In it, he introduced his new project: a free operating system kernel. At the time, he called it &lt;em&gt;“just a hobby, won’t be big and professional like GNU.”&lt;/em&gt;  &lt;/p&gt;

&lt;p&gt;That “hobby” turned into &lt;strong&gt;Linux&lt;/strong&gt; — and the world of technology has never been the same.  &lt;/p&gt;




&lt;h2&gt;
  
  
  🌱 The Beginning
&lt;/h2&gt;

&lt;p&gt;Torvalds’ announcement on &lt;strong&gt;25 August 1991&lt;/strong&gt; sparked something special. By releasing his source code and inviting collaboration, he planted the seed for a project that would grow into a global movement. Developers everywhere joined in, contributing ideas, fixes, and improvements.  &lt;/p&gt;

&lt;p&gt;This &lt;strong&gt;open and collaborative model&lt;/strong&gt; became the DNA of Linux, and it remains its strength to this day.  &lt;/p&gt;




&lt;h2&gt;
  
  
  📜 Key Milestones in Linux History
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;25 Aug 1991&lt;/strong&gt; – Linus Torvalds announces Linux to the world.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;1992&lt;/strong&gt; – Linux adopts the GNU General Public License (GPL), ensuring it remains free and open-source.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;1996&lt;/strong&gt; – &lt;strong&gt;Tux the Penguin&lt;/strong&gt;, designed by Larry Ewing, becomes the official Linux mascot.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;2000s&lt;/strong&gt; – Linux becomes the backbone of the internet, powering the majority of servers.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;2008&lt;/strong&gt; – Android, built on the Linux kernel, begins transforming the mobile industry.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Today&lt;/strong&gt; – Linux powers &lt;strong&gt;96% of the top 1 million servers&lt;/strong&gt;, &lt;strong&gt;all of the world’s top 500 supercomputers&lt;/strong&gt;, and is at the heart of cloud platforms, containers, and IoT.
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🌍 The Impact of Linux
&lt;/h2&gt;

&lt;p&gt;Linux is more than an operating system — it’s a &lt;strong&gt;philosophy and a community&lt;/strong&gt;.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Freedom&lt;/strong&gt; – Anyone can study, modify, and share it.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Collaboration&lt;/strong&gt; – Thousands of contributors worldwide continue to evolve it.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Innovation&lt;/strong&gt; – From smartphones to space missions, Linux makes the impossible possible.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without Linux, the internet, mobile computing, AI research, and even cloud platforms would look completely different.  &lt;/p&gt;




&lt;h2&gt;
  
  
  🎉 Celebrating Linux Today
&lt;/h2&gt;

&lt;p&gt;Though we’re a little late to say it:  &lt;/p&gt;

&lt;p&gt;🎉 &lt;strong&gt;Happy Belated Birthday, Linux!&lt;/strong&gt; 🐧  &lt;/p&gt;

&lt;p&gt;More than three decades later, Linux remains a symbol of openness, stability, and progress. From students learning their first command line to engineers deploying global infrastructure — Linux belongs to everyone.  &lt;/p&gt;

&lt;p&gt;Here’s to the next chapter of innovation and community-driven growth. 💻✨  &lt;/p&gt;

</description>
      <category>linux</category>
    </item>
    <item>
      <title>Choosing `UUID` for Unique IDs in a Multi-System Environment</title>
      <dc:creator>Siswoyo Siswoyo</dc:creator>
      <pubDate>Sat, 23 Aug 2025 11:42:41 +0000</pubDate>
      <link>https://dev.to/siswoyo/choosing-uuid-for-unique-ids-in-a-multi-system-environment-15e1</link>
      <guid>https://dev.to/siswoyo/choosing-uuid-for-unique-ids-in-a-multi-system-environment-15e1</guid>
      <description>&lt;p&gt;When designing a database schema, the choice of unique identifier is critical for &lt;strong&gt;scalability&lt;/strong&gt;, &lt;strong&gt;data integration&lt;/strong&gt;, and &lt;strong&gt;future-proofing&lt;/strong&gt;. While databases traditionally use &lt;code&gt;SERIAL&lt;/code&gt; (auto-increment integers), in modern distributed and service-oriented architectures, &lt;strong&gt;&lt;code&gt;UUID&lt;/code&gt; (Universally Unique Identifier)&lt;/strong&gt; is often the better choice.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Not &lt;code&gt;SERIAL&lt;/code&gt;?
&lt;/h2&gt;

&lt;p&gt;A &lt;code&gt;SERIAL&lt;/code&gt; or &lt;code&gt;BIGSERIAL&lt;/code&gt; column generates sequential IDs (&lt;code&gt;1, 2, 3...&lt;/code&gt;). This works fine for a single, isolated database but creates challenges when scaling:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ID collisions during merges&lt;/strong&gt;: Two different systems may both have a record with &lt;code&gt;id = 100&lt;/code&gt;. Merging them becomes complex.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Predictable IDs&lt;/strong&gt;: The sequence can reveal the number of records (e.g., knowing you have 50,000 customers).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sharding and replication issues&lt;/strong&gt;: Multiple services writing to their own databases may generate overlapping IDs.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Why Use &lt;code&gt;UUID&lt;/code&gt; Everywhere?
&lt;/h2&gt;

&lt;p&gt;A &lt;code&gt;UUID&lt;/code&gt; is a 128-bit identifier that is &lt;strong&gt;globally unique&lt;/strong&gt;. Using UUIDs for both &lt;strong&gt;master tables&lt;/strong&gt; (e.g., &lt;code&gt;customers&lt;/code&gt;, &lt;code&gt;products&lt;/code&gt;) and &lt;strong&gt;transaction tables&lt;/strong&gt; (e.g., &lt;code&gt;orders&lt;/code&gt;, &lt;code&gt;invoices&lt;/code&gt;) brings key benefits:&lt;/p&gt;

&lt;h3&gt;
  
  
  ✅ Advantages
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Seamless data merging&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Whether merging customers or orders across services, IDs will never clash. This simplifies integration projects.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Supports distributed systems&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Microservices, event-driven architectures, and multi-database systems can generate IDs independently without coordination.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Future-proofing&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Even if today you only have one database, tomorrow you might need to replicate, shard, or consolidate with another system.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Security&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
UUIDs are non-sequential, making it harder for outsiders to guess the number of records or enumerate IDs.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  ⚠️ Trade-offs
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Larger storage size (16 bytes vs. 4 bytes for integers).&lt;/li&gt;
&lt;li&gt;Slightly slower indexing and joins.&lt;/li&gt;
&lt;li&gt;Harder to read/debug manually (though often hidden behind APIs).&lt;/li&gt;
&lt;/ul&gt;




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

&lt;h3&gt;
  
  
  Master Table: Customers
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="n"&gt;EXTENSION&lt;/span&gt; &lt;span class="n"&gt;IF&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;EXISTS&lt;/span&gt; &lt;span class="nv"&gt;"uuid-ossp"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;customers&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;customer_id&lt;/span&gt; &lt;span class="n"&gt;UUID&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="n"&gt;uuid_generate_v4&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&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="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&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="k"&gt;UNIQUE&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Transaction Table: Orders
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;order_id&lt;/span&gt; &lt;span class="n"&gt;UUID&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="n"&gt;uuid_generate_v4&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="n"&gt;customer_id&lt;/span&gt; &lt;span class="n"&gt;UUID&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt; &lt;span class="k"&gt;REFERENCES&lt;/span&gt; &lt;span class="n"&gt;customers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;order_date&lt;/span&gt; &lt;span class="nb"&gt;TIMESTAMP&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="n"&gt;amount&lt;/span&gt; &lt;span class="nb"&gt;NUMERIC&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;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Final Decision
&lt;/h2&gt;

&lt;p&gt;If your system &lt;strong&gt;might merge data across multiple databases, services, or environments,&lt;/strong&gt;&lt;br&gt;
then the &lt;strong&gt;consistent choice is to use UUID for all primary keys&lt;/strong&gt; — both &lt;strong&gt;master data&lt;/strong&gt; and &lt;strong&gt;transactional data&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This avoids conflicts, simplifies future integrations, and aligns with best practices for distributed systems.&lt;/p&gt;

</description>
      <category>database</category>
      <category>sql</category>
      <category>microservices</category>
      <category>eventdriven</category>
    </item>
  </channel>
</rss>
