<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Werner Smit</title>
    <description>The latest articles on Forem by Werner Smit (@werner_smit).</description>
    <link>https://forem.com/werner_smit</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2998058%2F63401dd2-1425-4747-9fd6-1055d95e20aa.jpg</url>
      <title>Forem: Werner Smit</title>
      <link>https://forem.com/werner_smit</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/werner_smit"/>
    <language>en</language>
    <item>
      <title>Python's Hidden Bottleneck: How Startup Time Could Impact Your DevOps Pipelines</title>
      <dc:creator>Werner Smit</dc:creator>
      <pubDate>Thu, 10 Apr 2025 07:15:25 +0000</pubDate>
      <link>https://forem.com/werner_smit/pythons-startup-tax-when-script-startup-time-becomes-the-bottleneck-2np6</link>
      <guid>https://forem.com/werner_smit/pythons-startup-tax-when-script-startup-time-becomes-the-bottleneck-2np6</guid>
      <description>&lt;p&gt;Python is often criticized for being slow, but in most real-world applications, its performance is more than adequate. The language’s flexibility, readability, and rich ecosystem usually outweigh the cost of a few extra milliseconds in execution.&lt;/p&gt;

&lt;p&gt;That said, Python’s performance does become a concern in one specific area: &lt;strong&gt;startup time&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Python has a noticeable startup overhead, and this can become a real bottleneck in scenarios like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;High-frequency, short-lived scripts&lt;/strong&gt; — such as those used in DevOps pipelines to query APIs, interact with databases, or perform quick checks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lightweight OS-level tasks&lt;/strong&gt; — like verifying the status of a process or checking for the existence of a file.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Workflows that repeatedly invoke Python scripts in rapid succession&lt;/strong&gt; — where the cumulative startup time can dwarf the time spent doing actual work.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In these cases, Python’s overhead can add up quickly—making alternative tools or persistent Python processes worth considering.&lt;/p&gt;

&lt;p&gt;This article will take a closer look at Python’s startup behavior, explore when it becomes a problem, and discuss practical ways to work around it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Python Requests vs. curl: A Startup Time Comparison
&lt;/h2&gt;

&lt;p&gt;To demonstrate Python’s startup overhead, I built a simple HTTP server with Flask and wrote a basic client using Python’s requests library. Here’s how it compares to curl in terms of execution time:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: see &lt;a href="//#server.py"&gt;server.py&lt;/a&gt; and &lt;a href="//#client-requests.py"&gt;client-requests.py&lt;/a&gt; for the code used to run the server and client.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Python (requests)&lt;/code&gt;:&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="nv"&gt;$ &lt;/span&gt;hyperfine &lt;span class="nt"&gt;-w&lt;/span&gt; 1 &lt;span class="s1"&gt;'python client-requests.py'&lt;/span&gt;
Benchmark 1: python client-requests.py
  Time &lt;span class="o"&gt;(&lt;/span&gt;mean ± σ&lt;span class="o"&gt;)&lt;/span&gt;:     153.6 ms ±   3.8 ms    &lt;span class="o"&gt;[&lt;/span&gt;User: 134.6 ms, System: 17.0 ms]
  Range &lt;span class="o"&gt;(&lt;/span&gt;min … max&lt;span class="o"&gt;)&lt;/span&gt;:   147.1 ms … 162.4 ms    19 runs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;curl&lt;/code&gt;:&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="nv"&gt;$ &lt;/span&gt;hyperfine &lt;span class="nt"&gt;-w&lt;/span&gt; 1 &lt;span class="s1"&gt;'curl 127.0.0.1:5001/api'&lt;/span&gt;
Benchmark 1: curl 127.0.0.1:5001/api
  Time &lt;span class="o"&gt;(&lt;/span&gt;mean ± σ&lt;span class="o"&gt;)&lt;/span&gt;:       6.2 ms ±   1.0 ms    &lt;span class="o"&gt;[&lt;/span&gt;User: 2.6 ms, System: 2.9 ms]
  Range &lt;span class="o"&gt;(&lt;/span&gt;min … max&lt;span class="o"&gt;)&lt;/span&gt;:     4.8 ms …   9.8 ms    353 runs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result:&lt;/strong&gt; &lt;code&gt;153ms&lt;/code&gt; vs &lt;code&gt;6ms&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That is a massive, &lt;strong&gt;25x&lt;/strong&gt; difference.&lt;/p&gt;

&lt;h2&gt;
  
  
  Python's Libraries: How Much Do Imports Affect Startup?
&lt;/h2&gt;

&lt;p&gt;While &lt;code&gt;requests&lt;/code&gt; is convenient, it seems to have a significant import overhead. Switching to Python's built-in &lt;code&gt;urllib&lt;/code&gt; demonstrates how lighter dependencies can improve startup times:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: see &lt;a href="//#client-urllib.py"&gt;client-urllib.py&lt;/a&gt; for the code used to run the client.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Startup Time Comparison&lt;/strong&gt;
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;Mean Time&lt;/th&gt;
&lt;th&gt;Relative Speed&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;curl&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;6.2 ms&lt;/td&gt;
&lt;td&gt;1x (baseline)&lt;/td&gt;
&lt;td&gt;Compiled binary, no imports&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;python (urllib)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;81.3 ms&lt;/td&gt;
&lt;td&gt;~13x slower&lt;/td&gt;
&lt;td&gt;Python stdlib, no deps&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;python (requests)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;153.6 ms&lt;/td&gt;
&lt;td&gt;~25x slower&lt;/td&gt;
&lt;td&gt;Heavy dependency chain&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Benchmark Details:&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;&lt;span class="nv"&gt;$ &lt;/span&gt;hyperfine &lt;span class="nt"&gt;-w&lt;/span&gt; 1 &lt;span class="s1"&gt;'python client-urllib.py'&lt;/span&gt;
  Time &lt;span class="o"&gt;(&lt;/span&gt;mean ± σ&lt;span class="o"&gt;)&lt;/span&gt;:      81.3 ms ±   8.9 ms
  Range &lt;span class="o"&gt;(&lt;/span&gt;min … max&lt;span class="o"&gt;)&lt;/span&gt;:    71.7 ms … 111.6 ms    41 runs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# requests (from earlier)&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;hyperfine &lt;span class="nt"&gt;-w&lt;/span&gt; 1 &lt;span class="s1"&gt;'python client-requests.py'&lt;/span&gt;
  Time &lt;span class="o"&gt;(&lt;/span&gt;mean ± σ&lt;span class="o"&gt;)&lt;/span&gt;:     153.6 ms ±   3.8 ms
  Range &lt;span class="o"&gt;(&lt;/span&gt;min … max&lt;span class="o"&gt;)&lt;/span&gt;:   147.1 ms … 162.4 ms    19 runs

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why Is the Python Script So Slow?
&lt;/h2&gt;

&lt;p&gt;In short, Python is an interpreted language, so running a script doesn’t just execute your HTTP request, it spins up an entire interpreter. Before your code runs, Python performs significant groundwork, which introduces substantial overhead for short-lived tasks. The size of the overhead depends on the &lt;strong&gt;number of modules imported&lt;/strong&gt; and the complexity of the script.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dependency Bloat Matters&lt;/strong&gt;:&lt;br&gt;
Heavyweight libraries like &lt;code&gt;requests&lt;/code&gt; exacerbate Python’s startup penalty.&lt;/p&gt;
&lt;h3&gt;
  
  
  Breakdown of Python Startup Time
&lt;/h3&gt;

&lt;p&gt;The table below dissects the time taken at each stage of running the Python script:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Test&lt;/th&gt;
&lt;th&gt;Time (ms)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;python -c 'print("hello world")'&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;54 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;python -c 'from urllib.request import Request'&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;64 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;python -c 'import requests'&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;150 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;python client-urllib.py&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;77 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;python client-requests.py&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;153 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;requests.get()&lt;/code&gt; (request only)&lt;/td&gt;
&lt;td&gt;1.3 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Notice how the actual HTTP request (&lt;code&gt;requests.get()&lt;/code&gt;) takes just &lt;strong&gt;1.3 ms&lt;/strong&gt;—the rest is consumed by interpreter startup and module imports, which are unavoidable in standard Python.&lt;/p&gt;
&lt;h2&gt;
  
  
  Does Pre-Compiling Help?
&lt;/h2&gt;

&lt;p&gt;One might assume pre-compiling the script (e.g., using &lt;code&gt;.pyc&lt;/code&gt; files or tools like Cython) would reduce startup time. Unfortunately, this &lt;strong&gt;doesn’t address the core issue&lt;/strong&gt;: the interpreter must still initialize, and imported modules (like &lt;code&gt;requests&lt;/code&gt;) must be loaded. Pre-compilation optimizes runtime execution, not startup.&lt;/p&gt;
&lt;h3&gt;
  
  
  Standard compiler
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; compileall client-requests.py
Compiling &lt;span class="s1"&gt;'client-requests.py'&lt;/span&gt;...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Nuitka
&lt;/h3&gt;

&lt;p&gt;Nuitka is a Python-to-C++ compiler that can compile Python scripts into standalone executables. It can be used to compile Python scripts into binary executables, which can be run without requiring a Python interpreter. This can potentially improve performance.&lt;/p&gt;

&lt;p&gt;Compiling the script:&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="nv"&gt;$ &lt;/span&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; nuitka &lt;span class="nt"&gt;--standalone&lt;/span&gt; &lt;span class="nt"&gt;--onefile&lt;/span&gt; client-requests.py
..
Nuitka: Successfully created &lt;span class="s1"&gt;'client-requests.bin'&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Benchmarking the compiled python scripts
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;hyperfine &lt;span class="nt"&gt;-w&lt;/span&gt; 1 &lt;span class="s1"&gt;'python client-requests.py'&lt;/span&gt;
Benchmark 1: python client-requests.py
  Time &lt;span class="o"&gt;(&lt;/span&gt;mean ± σ&lt;span class="o"&gt;)&lt;/span&gt;:     152.7 ms ±  10.2 ms    &lt;span class="o"&gt;[&lt;/span&gt;User: 131.3 ms, System: 19.7 ms]
  Range &lt;span class="o"&gt;(&lt;/span&gt;min … max&lt;span class="o"&gt;)&lt;/span&gt;:   141.7 ms … 170.0 ms    20 runs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;hyperfine &lt;span class="nt"&gt;-w&lt;/span&gt; 1 &lt;span class="s1"&gt;'python __pycache__/client-requests.cpython-313.pyc'&lt;/span&gt;
Benchmark 1: python __pycache__/client-requests.cpython-313.pyc
  Time &lt;span class="o"&gt;(&lt;/span&gt;mean ± σ&lt;span class="o"&gt;)&lt;/span&gt;:     160.9 ms ±  17.4 ms    &lt;span class="o"&gt;[&lt;/span&gt;User: 140.1 ms, System: 18.9 ms]
  Range &lt;span class="o"&gt;(&lt;/span&gt;min … max&lt;span class="o"&gt;)&lt;/span&gt;:   143.3 ms … 194.1 ms    20 runs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;hyperfine &lt;span class="nt"&gt;-w&lt;/span&gt; 1 &lt;span class="s1"&gt;'./client-requests.bin'&lt;/span&gt;
Benchmark 1: ./client-requests.bin
  Time &lt;span class="o"&gt;(&lt;/span&gt;mean ± σ&lt;span class="o"&gt;)&lt;/span&gt;:     257.9 ms ±   9.2 ms    &lt;span class="o"&gt;[&lt;/span&gt;User: 211.9 ms, System: 41.5 ms]
  Range &lt;span class="o"&gt;(&lt;/span&gt;min … max&lt;span class="o"&gt;)&lt;/span&gt;:   246.9 ms … 279.5 ms    10 runs

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Compiled vs. Uncompiled Startup Time Results
&lt;/h3&gt;

&lt;p&gt;In a surprising twist, the Nuitka-compiled script was &lt;strong&gt;68% slower&lt;/strong&gt; than the original, taking &lt;strong&gt;257ms&lt;/strong&gt; versus &lt;strong&gt;152ms&lt;/strong&gt; for pure Python. The &lt;code&gt;compileall&lt;/code&gt; approach, as expected, showed no meaningful difference (~160ms), since benchmarking with a warmup phase already leverages cached bytecode (&lt;code&gt;pyc&lt;/code&gt; files).&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Test&lt;/th&gt;
&lt;th&gt;Time (ms)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Pure Python&lt;/td&gt;
&lt;td&gt;152 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Python + &lt;code&gt;compileall&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;160 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Python + &lt;strong&gt;Nuitka&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;257 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Why Nuitka Slows Startup&lt;/strong&gt;:&lt;br&gt;
Nuitka adds overhead by bundling the CPython runtime and dependencies into a binary. While this helps distribution, it &lt;em&gt;increases&lt;/em&gt; startup time due to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Binary unpacking and linking.&lt;/li&gt;
&lt;li&gt;Retained CPython interpreter initialization.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Python’s startup penalty is &lt;strong&gt;unavoidable&lt;/strong&gt; for short-lived processes. While acceptable for one-off tasks (e.g., starting a web server), it becomes problematic when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Called repeatedly in loops&lt;/strong&gt; (e.g., processing each file in a directory separately)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Used for trivial operations&lt;/strong&gt; (e.g., single API calls, checking if a file exists)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Run as frequent cron jobs&lt;/strong&gt; (where milliseconds add up)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Used in shell pipelines&lt;/strong&gt; (where Python is called for each input line)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Alternatives
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Use lighter dependencies&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Replace &lt;code&gt;requests&lt;/code&gt; with &lt;code&gt;urllib&lt;/code&gt; or &lt;code&gt;httpx&lt;/code&gt; (if startup is critical).&lt;/li&gt;
&lt;li&gt;Avoid large frameworks (e.g., &lt;code&gt;pandas&lt;/code&gt;, &lt;code&gt;tensorflow&lt;/code&gt;) for trivial tasks.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reduce Invocations&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Batch work (e.g., process 100 files in one script call instead of 100 calls).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use Shell Tools&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Replace Python with &lt;code&gt;curl&lt;/code&gt;/&lt;code&gt;jq&lt;/code&gt; for HTTP or &lt;code&gt;grep&lt;/code&gt;/&lt;code&gt;awk&lt;/code&gt; for text processing.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Switch to Compiled Languages&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;For sub-10ms startup, use &lt;strong&gt;Go&lt;/strong&gt; (simple) or &lt;strong&gt;Rust&lt;/strong&gt; (performance-critical).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight&lt;/strong&gt;: Python trades startup speed for runtime flexibility. Choose the right tool for the job.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  &lt;em&gt;References&lt;/em&gt;
&lt;/h2&gt;
&lt;h3&gt;
  
  
  &lt;em&gt;System information&lt;/em&gt;
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; OS: Arch Linux
 Kernel: x86_64 Linux 6.12.20-1-lts
 Uptime: 4d 18h 26m
 Shell: zsh 5.9
 CPU: Intel Core i5-8350U @ 8x 3.6GHz [59.0°C]
 GPU: Mesa Intel(R) UHD Graphics 620 (KBL GT2)
 RAM: 5986MiB / 15734MiB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  &lt;em&gt;Python version&lt;/em&gt;
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;python &lt;span class="nt"&gt;-V&lt;/span&gt;
Python 3.13.2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  &lt;em&gt;Measurement and setup&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;Here's how the &lt;code&gt;request.get&lt;/code&gt; was measured:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; timeit &lt;span class="nt"&gt;-n&lt;/span&gt; 10 &lt;span class="nt"&gt;-r&lt;/span&gt; 3 &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"import requests"&lt;/span&gt; &lt;span class="s2"&gt;"requests.get('http://127.0.0.1:5001/api').json()"&lt;/span&gt;
10 loops, best of 3: 1.37 msec per loop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;em&gt;server.py&lt;/em&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;flask&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Flask&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;jsonify&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Flask&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="nd"&gt;@app.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/api&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;methods&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;GET&lt;/span&gt;&lt;span class="sh"&gt;'&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;handle_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;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;method&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;GET&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;jsonify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;message&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GET request received&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]})&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;0.0.0.0&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5001&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;debug&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the server using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python server.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;em&gt;client-requests.py&lt;/em&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;

&lt;span class="c1"&gt;# Base URL of the server
&lt;/span&gt;&lt;span class="n"&gt;BASE_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;http://localhost:5001/api&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_data&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BASE_URL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GET Response:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&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;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;get_data&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the client using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python client-requests.py
GET Response: &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'data'&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;1, 2, 3], &lt;span class="s1"&gt;'message'&lt;/span&gt;: &lt;span class="s1"&gt;'GET request received'&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;em&gt;client-urllib.py&lt;/em&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;urllib.request&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;urlopen&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;

&lt;span class="n"&gt;BASE_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;http://localhost:5001/api&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_data&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;req&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BASE_URL&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;urlopen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&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;response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;utf-8&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GET Response:&lt;/span&gt;&lt;span class="sh"&gt;"&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;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;get_data&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the client using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python client-urllib.py
GET Response: &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'data'&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;1, 2, 3], &lt;span class="s1"&gt;'message'&lt;/span&gt;: &lt;span class="s1"&gt;'GET request received'&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>python</category>
      <category>performance</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
