<?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: Oluwajubelo</title>
    <description>The latest articles on DEV Community by Oluwajubelo (@oluwajubelo1).</description>
    <link>https://dev.to/oluwajubelo1</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%2F837057%2Febb5bfb1-2dea-413b-aca4-fc46902417da.jpeg</url>
      <title>DEV Community: Oluwajubelo</title>
      <link>https://dev.to/oluwajubelo1</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/oluwajubelo1"/>
    <language>en</language>
    <item>
      <title>Stop bleeding money on LLMs: Introducing Otellix for Go</title>
      <dc:creator>Oluwajubelo</dc:creator>
      <pubDate>Sun, 29 Mar 2026 22:08:01 +0000</pubDate>
      <link>https://dev.to/oluwajubelo1/stop-bleeding-money-on-llms-introducing-otellix-for-go-500c</link>
      <guid>https://dev.to/oluwajubelo1/stop-bleeding-money-on-llms-introducing-otellix-for-go-500c</guid>
      <description>&lt;p&gt;Working with Large Language Models (LLMs) in production is magic. The honeymoon phase usually lasts about a month—right until you get the inevitable API bill.&lt;/p&gt;

&lt;p&gt;If you’ve ever accidentally put an LLM generation call inside a deeply nested background loop (don't lie, we've all done it), or if you just want to prevent one heavy user from eating your organization's daily budget, then you probably know the pain.&lt;/p&gt;

&lt;p&gt;Current LLM observability platforms are either heavy SaaS products with their own per-event pricing, or they completely lack hard budget enforcement. I wanted something free, OpenTelemetry-native, and focused on hard budget limits for cost-constrained applications in Go.&lt;/p&gt;

&lt;p&gt;So, I built &lt;strong&gt;&lt;a href="https://github.com/oluwajubelo1/otellix" rel="noopener noreferrer"&gt;Otellix&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

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

&lt;p&gt;Otellix is a production-grade LLM observability SDK for Go built entirely on top of OpenTelemetry. It wraps the official SDKs for Anthropic, OpenAI, Gemini, and Ollama, allowing you to intercept and track costs without drastically altering your codebase.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Unified Tracing &amp;amp; Metrics
&lt;/h3&gt;

&lt;p&gt;Every LLM generation call emits unified OTel spans and Prometheus metrics. Wait exactly how many input tokens, output tokens, and cached tokens did that user generate last week? Otellix handles all of that out of the box, standardizing the response payloads of 4 completely different vendors.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Zero-Latency Cost Engine
&lt;/h3&gt;

&lt;p&gt;Different LLM providers have very different pricing models depending on context-window caching. Otellix ships with an in-memory Cost Engine synced to 2026-era USD pricing models. The cost of a request is immediately available in the returning &lt;code&gt;CallResult&lt;/code&gt; struct, meaning you deal with pennies, not abstract tokens.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;otellix&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"That request cost $%.6f&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CostUSD&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Hard Budget Guardrails
&lt;/h3&gt;

&lt;p&gt;This is the core feature. What do you do when a user hits their $5/day LLM quota?&lt;br&gt;
Instead of building complex Redis limiters yourself, you can plug in Otellix's &lt;code&gt;BudgetEnforcer&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It ships with three fallback mechanisms:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;FallbackBlock&lt;/code&gt;: Immediately stops the LLM execution and returns an &lt;code&gt;otellix.ErrBudgetExceeded&lt;/code&gt; error instead of hitting the vendor API.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;FallbackNotify&lt;/code&gt;: Allows the request to go through, but triggers an asynchronous &lt;code&gt;onLimitReached&lt;/code&gt; callback webhook (perfect for Slack alerts).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;FallbackDowngrade&lt;/code&gt;: &lt;strong&gt;(My personal favorite)&lt;/strong&gt; If a user runs out of "premium" tokens for &lt;code&gt;claude-3-opus&lt;/code&gt;, Otellix will automatically intercept the request and execute it via a cheaper provider/model like &lt;code&gt;gemini-1.5-flash&lt;/code&gt; or a locally hosted &lt;code&gt;ollama&lt;/code&gt; container instead.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Code Example
&lt;/h2&gt;

&lt;p&gt;Here's how easy it is to wrap your existing OpenAI logic:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;store&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;otellix&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewInMemoryBudgetStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;float64&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s"&gt;"user_123"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2.50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c"&gt;// Hard limit of $2.50&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="n"&gt;enforcer&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;otellix&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewBudgetEnforcer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;store&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;otellix&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FallbackBlock&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;cfg&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;otellix&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;otellix&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithBudgetEnforcer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;enforcer&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;// Your existing OpenAI client logic&lt;/span&gt;
&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;openai&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"sk-..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 

&lt;span class="c"&gt;// Wrap the request in Otellix!&lt;/span&gt;
&lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;otellix&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;params&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;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatalf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"LLM tracking failed: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&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;h3&gt;
  
  
  Getting Started
&lt;/h3&gt;

&lt;p&gt;Otellix is fully open source (MIT) and available now! Oh, and the repository even includes a full &lt;code&gt;docker-compose&lt;/code&gt; environment complete with Prometheus and Grafana dashboards for local testing.&lt;/p&gt;

&lt;p&gt;Drop a star if you find it useful:&lt;br&gt;
👉 &lt;strong&gt;&lt;a href="https://github.com/oluwajubelo1/otellix" rel="noopener noreferrer"&gt;GitHub: oluwajubelo1/otellix&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I’d love to know how you're currently dealing with rogue LLM costs in your Go backends—let me know in the comments below!&lt;/p&gt;

</description>
      <category>go</category>
      <category>opensource</category>
      <category>observability</category>
      <category>ai</category>
    </item>
    <item>
      <title>Caching Strategies and Optimization in Laravel</title>
      <dc:creator>Oluwajubelo</dc:creator>
      <pubDate>Tue, 26 Aug 2025 08:49:20 +0000</pubDate>
      <link>https://dev.to/oluwajubelo1/caching-strategies-and-optimization-in-laravel-1h5e</link>
      <guid>https://dev.to/oluwajubelo1/caching-strategies-and-optimization-in-laravel-1h5e</guid>
      <description>&lt;p&gt;In today’s fast-paced digital world, speed is everything. Whether you’re building a fintech platform, an e-commerce store, or a social app, users expect instant responses. But as your application grows, database queries and heavy computations can slow things down.&lt;/p&gt;

&lt;p&gt;That’s where caching comes into play.&lt;/p&gt;

&lt;p&gt;Think of caching like having a &lt;strong&gt;photocopy of a document&lt;/strong&gt;: instead of rewriting the entire report (expensive database query), you just pull out the copy (cached data). Much faster, right? Laravel makes this super easy with its built-in caching system.&lt;/p&gt;

&lt;h4&gt;
  
  
  Why Caching Matters in Laravel
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Reduce database load → Expensive queries run less often.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Speed up APIs → Responses can be served in milliseconds.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Save resources → Lower CPU and memory usage, better scalability.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The result? A faster, smoother experience for your users.&lt;/p&gt;

&lt;h4&gt;
  
  
  Laravel Cache Drivers
&lt;/h4&gt;

&lt;p&gt;Laravel supports several cache drivers (configured in &lt;code&gt;config/cache.php&lt;/code&gt;):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;File – Stores cache in files. Easy, but slower for large apps.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Database – Uses a database table for caching. Useful but can get heavy.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Redis (recommended) – Super fast, in-memory store.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Memcached – Another great option for high-performance caching.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example setup in &lt;code&gt;.env&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CACHE_DRIVER=redis
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Caching Strategies in Laravel
&lt;/h4&gt;

&lt;p&gt;Here are some of the most effective caching approaches you can use:&lt;/p&gt;

&lt;h5&gt;
  
  
  1. Cache Database Queries
&lt;/h5&gt;

&lt;p&gt;Instead of running queries every time, cache the results:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$users = Cache::remember('users_list', 60, function () {
    return User::all();
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;How it works:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;First request → fetches from DB, saves in cache for 60 seconds.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Next requests → served instantly from cache.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;
  
  
  2. Cache Forever (until manually cleared)
&lt;/h5&gt;

&lt;p&gt;For rarely changing data like a list of countries:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$countries = Cache::rememberForever('countries', function () {
    return Country::all();
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Clear when necessary:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Cache::forget('countries');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  3. Partial Page Caching (View Fragments)
&lt;/h5&gt;

&lt;p&gt;Instead of caching entire pages, cache sections like menus, sidebars, or widgets.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@cache('sidebar_menu')
    &amp;lt;ul&amp;gt;
        @foreach($categories as $cat)
            &amp;lt;li&amp;gt;{{ $cat-&amp;gt;name }}&amp;lt;/li&amp;gt;
        @endforeach
    &amp;lt;/ul&amp;gt;
@endcache
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(This may need a package like Spatie’s Laravel ResponseCache.)&lt;/p&gt;

&lt;h5&gt;
  
  
  4. Route, Config, and View Caching
&lt;/h5&gt;

&lt;p&gt;Laravel allows you to cache app configurations and routes for blazing-fast performance:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;php artisan route:cache
php artisan config:cache
php artisan view:cache
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Always run these in production for optimal speed.&lt;/p&gt;

&lt;h5&gt;
  
  
  5. Tagged Caching
&lt;/h5&gt;

&lt;p&gt;When you need grouped cache that can be flushed together:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Cache::tags(['products'])-&amp;gt;remember('featured_products', 600, function () {
    return Product::where('featured', true)-&amp;gt;get();
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Clear all product-related cache at once:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Cache::tags(['products'])-&amp;gt;flush();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  6. Query Caching with Eloquent
&lt;/h5&gt;

&lt;p&gt;Cache paginated queries or relationship-heavy queries:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$posts = Cache::remember('posts_page_1', 120, function () {
    return Post::with('author')-&amp;gt;paginate(10);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  7. Cache Busting
&lt;/h5&gt;

&lt;p&gt;What if cached data goes stale? Bust it whenever updates happen.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User::create([...]);
Cache::forget('users_list');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Real-World Example&lt;/p&gt;

&lt;p&gt;Imagine a fintech dashboard that displays:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;User balance&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Recent transactions&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Market data&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without caching:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Every request hits the DB + external APIs → slow.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With caching:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$balance = Cache::remember("balance_user_{$user-&amp;gt;id}", 30, function () use ($user) {
    return $user-&amp;gt;calculateBalance();
});

$transactions = Cache::remember("transactions_user_{$user-&amp;gt;id}", 60, function () use ($user) {
    return $user-&amp;gt;transactions()-&amp;gt;latest()-&amp;gt;take(10)-&amp;gt;get();
});

$marketData = Cache::remember("market_data", 300, function () {
    return Http::get('https://api.example.com/market')-&amp;gt;json();
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Result:&lt;/p&gt;

&lt;p&gt;-Balance refreshes every 30s.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Transactions refresh every 1min.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Market data refreshes every 5min.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Optimization Tips
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Use Redis in production (faster than file/database caching).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Don’t over-cache—only cache expensive queries or slow computations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Always invalidate smartly when data changes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Combine caching with queues for heavy background tasks.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use tools like Laravel Telescope or Debugbar to find cache opportunities.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Final Thoughts
&lt;/h4&gt;

&lt;p&gt;Caching in Laravel is like giving your app superpowers. Done right, it makes your system feel lightweight, scalable, and lightning fast. The secret is knowing &lt;strong&gt;what to cache and when to refresh&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Think of caching as &lt;strong&gt;keeping photocopies of your most-used notes&lt;/strong&gt;: instead of rewriting them every time, you just pull them out instantly.&lt;/p&gt;

&lt;p&gt;So, if you’re serious about optimization, caching isn’t optional—it’s &lt;strong&gt;essential&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>php</category>
      <category>redis</category>
      <category>optimization</category>
    </item>
    <item>
      <title>Caddy: The Modern Web Server That Makes HTTPS Easy</title>
      <dc:creator>Oluwajubelo</dc:creator>
      <pubDate>Tue, 24 Jun 2025 09:15:14 +0000</pubDate>
      <link>https://dev.to/oluwajubelo1/caddy-the-modern-web-server-that-makes-https-easy-ll7</link>
      <guid>https://dev.to/oluwajubelo1/caddy-the-modern-web-server-that-makes-https-easy-ll7</guid>
      <description>&lt;p&gt;If you're getting into web development or server administration, you've probably heard of web servers like Apache and Nginx. But there's a newer player in the game that's gaining popularity for its simplicity and powerful features: Caddy. Let's explore what makes Caddy special and how it compares to the more established Nginx.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is Caddy?
&lt;/h3&gt;

&lt;p&gt;Caddy is a modern, open-source web server written in Go. What sets it apart from traditional web servers is its focus on simplicity, automatic HTTPS, and ease of configuration. While servers like Apache and Nginx have been around for decades, Caddy was built from the ground up with modern web standards and developer experience in mind.&lt;/p&gt;

&lt;p&gt;Think of Caddy as the "smart" web server that handles many complex tasks automatically, so you don't have to worry about them. It's particularly popular among developers who want to get a secure website up and running quickly without diving deep into server configuration.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Features of Caddy
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Automatic HTTPS
&lt;/h4&gt;

&lt;p&gt;Perhaps Caddy's most celebrated feature is its automatic HTTPS capability. When you configure a site with Caddy, it automatically obtains and renews SSL/TLS certificates from Let's Encrypt. This means your websites are encrypted by default without any manual certificate management.&lt;/p&gt;

&lt;h3&gt;
  
  
  Simple Configuration
&lt;/h3&gt;

&lt;p&gt;Caddy uses a human-readable configuration format called the Caddyfile. Instead of complex configuration blocks, you can set up a basic website with just a few lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;example.com {
    root * /var/www/html
    file_server
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Built-in Features
&lt;/h3&gt;

&lt;p&gt;Caddy comes with many features built-in that would require additional modules or plugins in other web servers, including reverse proxy capabilities, load balancing, and automatic gzip compression.&lt;/p&gt;

&lt;h3&gt;
  
  
  HTTP/2 and HTTP/3 Support
&lt;/h3&gt;

&lt;p&gt;Caddy supports modern HTTP protocols out of the box, including HTTP/2 and HTTP/3 (QUIC), providing better performance for modern web applications.&lt;/p&gt;

&lt;h3&gt;
  
  
  Caddy vs Nginx: A Detailed Comparison
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Configuration Complexity
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Caddy&lt;/strong&gt; shines with its simple, intuitive configuration. The Caddyfile format is designed to be readable by humans, not just machines. Setting up a reverse proxy or enabling HTTPS requires minimal configuration.&lt;br&gt;
&lt;strong&gt;Nginx&lt;/strong&gt; has a more complex configuration syntax that follows a block-based structure. While powerful and flexible, it has a steeper learning curve. Simple tasks might require more lines of configuration and deeper understanding of web server concepts.&lt;/p&gt;

&lt;h3&gt;
  
  
  HTTPS Setup
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Caddy&lt;/strong&gt; automatically handles SSL/TLS certificates. Just specify your domain, and Caddy takes care of obtaining, installing, and renewing certificates from Let's Encrypt.&lt;br&gt;
&lt;strong&gt;Nginx&lt;/strong&gt; requires manual certificate management. You need to obtain certificates separately, configure them in your Nginx configuration, and set up renewal processes. While tools like Certbot can automate this, it still requires additional setup steps.&lt;/p&gt;

&lt;h3&gt;
  
  
  Performance
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Nginx&lt;/strong&gt; has a proven track record for high-performance scenarios and can handle enormous amounts of concurrent connections efficiently. It's battle-tested in high-traffic environments and offers fine-grained performance tuning options.&lt;br&gt;
&lt;strong&gt;Caddy&lt;/strong&gt; performs well for most use cases but may not match Nginx's performance in extremely high-traffic scenarios. However, for small to medium-sized applications, the performance difference is often negligible.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ecosystem and Plugins
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Nginx&lt;/strong&gt; has a vast ecosystem of third-party modules and extensive documentation. It's been around longer, so you'll find more tutorials, Stack Overflow answers, and community resources.&lt;br&gt;
&lt;strong&gt;Caddy&lt;/strong&gt; has a growing plugin ecosystem, but it's smaller than Nginx's. However, Caddy's modular architecture makes it easy to extend functionality when needed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Resource Usage
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Caddy&lt;/strong&gt; generally uses more memory than Nginx due to its Go runtime and built-in features. However, it often requires fewer system resources overall because you don't need separate processes for certificate management and other tasks.&lt;br&gt;
&lt;strong&gt;Nginx&lt;/strong&gt; is known for its efficient memory usage and can run on minimal system resources, making it ideal for resource-constrained environments.&lt;/p&gt;

&lt;h3&gt;
  
  
  When to Choose Caddy
&lt;/h3&gt;

&lt;p&gt;Caddy is an excellent choice when you want to get a secure website running quickly without complex configuration. It's particularly well-suited for developers who prioritize simplicity and automatic HTTPS. Choose Caddy if you're building modern web applications, need quick prototyping capabilities, or want to minimize server administration overhead.&lt;/p&gt;

&lt;h3&gt;
  
  
  When to Choose Nginx
&lt;/h3&gt;

&lt;p&gt;Nginx remains the better choice for high-traffic websites that require maximum performance optimization, complex routing rules, or extensive customization. It's also preferred in enterprise environments where fine-grained control and proven scalability are essential.&lt;/p&gt;

&lt;h3&gt;
  
  
  Getting Started with Caddy
&lt;/h3&gt;

&lt;p&gt;If you want to try Caddy, getting started is straightforward. Install it on your system, create a simple Caddyfile, and run it. Within minutes, you can have a secure website running with automatic HTTPS.&lt;/p&gt;

&lt;h3&gt;
  
  
  Configuration Examples
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Basic Static Site (Caddy)
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mysite.com {
    root * /var/www/html
    file_server
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Basic Static Site (Nginx)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;server {
    listen 80;
    server_name mysite.com;
    root /var/www/html;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Reverse Proxy (Caddy)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;api.mysite.com {
    reverse_proxy localhost:8080
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Reverse Proxy (Nginx)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;server {
    listen 80;
    server_name api.mysite.com;

    location / {
        proxy_pass http://localhost:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Both Caddy and Nginx are powerful web servers, but they serve different needs. Caddy excels in simplicity and modern defaults, while Nginx offers maximum performance and flexibility. Your choice depends on your specific requirements, technical expertise, and the scale of your project.&lt;br&gt;
For beginners and developers who value simplicity, Caddy offers a refreshing approach to web server management. For high-performance applications requiring extensive customization, Nginx continues to be the gold standard.&lt;br&gt;
Whether you choose Caddy or Nginx, both will serve you well in your web development journey. Start with the one that matches your current needs and comfort level, and don't be afraid to explore both as you grow in your understanding of web server technologies.&lt;/p&gt;

</description>
      <category>caddy</category>
      <category>webserver</category>
      <category>devops</category>
      <category>programming</category>
    </item>
    <item>
      <title>Docker Multi-Stage Builds: Your Secret Weapon for Lean, Mean Container Machines</title>
      <dc:creator>Oluwajubelo</dc:creator>
      <pubDate>Mon, 09 Jun 2025 08:58:13 +0000</pubDate>
      <link>https://dev.to/oluwajubelo1/docker-multi-stage-builds-your-secret-weapon-for-lean-mean-container-machines-hl8</link>
      <guid>https://dev.to/oluwajubelo1/docker-multi-stage-builds-your-secret-weapon-for-lean-mean-container-machines-hl8</guid>
      <description>&lt;p&gt;Picture this: You've just finished building your latest web application. It's beautiful, it works perfectly, and you're ready to containerize it. You write your Dockerfile, build the image, and... it's 2GB. For a simple Node.js app. Your deployment pipeline is crying, your servers are groaning, and your wallet is getting lighter with every cloud storage bill.&lt;br&gt;
Sound familiar? Welcome to the world before multi-stage builds – where Docker images were bloated with build tools, source code, and dependencies that had no business being in production.&lt;/p&gt;
&lt;h4&gt;
  
  
  The Problem: When Docker Images Go on a Diet (But Refuse to Lose Weight)
&lt;/h4&gt;

&lt;p&gt;Let's start with a real-world scenario. You're building a React application that needs to be compiled and served by an Nginx server. Here's what your Dockerfile might look like without multi-stage builds:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dockerfile
FROM node:18
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
RUN npm install -g serve
EXPOSE 3000
CMD ["serve", "-s", "build"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This approach has several problems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Your final image includes Node.js, npm, and all development dependencies&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The source code and intermediate build files are still there&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The image size is unnecessarily large&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You're potentially exposing security vulnerabilities through unused tools&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's like moving houses but taking all your old furniture, broken appliances, and that box of cables you'll "definitely use someday" – except in this case, you're paying for storage and bandwidth for all that digital clutter.&lt;/p&gt;

&lt;h4&gt;
  
  
  Enter Multi-Stage Builds: The Marie Kondo of Docker
&lt;/h4&gt;

&lt;p&gt;Multi-stage builds allow you to use multiple &lt;code&gt;FROM&lt;/code&gt; statements in your Dockerfile. Each &lt;code&gt;FROM&lt;/code&gt; instruction starts a new build stage, and you can selectively copy artifacts from one stage to another, leaving behind everything you don't want in the final image.&lt;br&gt;
Think of it as a relay race where each runner (stage) passes only what's necessary to the next runner, rather than carrying the entire team's equipment to the finish line.&lt;/p&gt;
&lt;h4&gt;
  
  
  Real-World Example 1: The React Application Transformation
&lt;/h4&gt;

&lt;p&gt;Let's transform our bloated React app Dockerfile into a lean, multi-stage masterpiece:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dockerfile
# Stage 1: Build the application
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build

# Stage 2: Serve the application
FROM nginx:alpine
COPY --from=builder /app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  What just happened here?
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Stage 1 (builder): We use Node.js to install dependencies and build our React app&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Stage 2 (final): We use a lightweight Nginx image and copy only the built files&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  The results are dramatic:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Original image: ~1.2GB&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Multi-stage image: ~25MB&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;That's a 98% reduction in size!&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Real-World Example 2: Go Application - From Gigabytes to Megabytes
&lt;/h4&gt;

&lt;p&gt;Go applications are perfect candidates for multi-stage builds because Go compiles to static binaries. Here's a typical Go web service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dockerfile
# Stage 1: Build the Go binary
FROM golang:1.21-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o main .

# Stage 2: Create minimal runtime image
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /app/main .
EXPOSE 8080
CMD ["./main"]

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

&lt;/div&gt;



&lt;h4&gt;
  
  
  Even better - using scratch:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dockerfile
# Stage 1: Build
FROM golang:1.21-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main .

# Stage 2: Ultra-minimal image
FROM scratch
COPY --from=builder /app/main /
EXPOSE 8080
ENTRYPOINT ["/main"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates an image that's literally just your binary – we're talking about images under 10MB for most Go applications!&lt;/p&gt;

&lt;h4&gt;
  
  
  Real-World Example 3: Python Flask Application with Poetry
&lt;/h4&gt;

&lt;p&gt;Python applications often have complex dependency management. Here's how to handle a Flask app using Poetry:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dockerfile
# Stage 1: Build dependencies
FROM python:3.11-slim AS builder
RUN pip install poetry
WORKDIR /app
COPY pyproject.toml poetry.lock ./
RUN poetry config virtualenvs.create false \
    &amp;amp;&amp;amp; poetry install --only=main --no-root
COPY . .
RUN poetry build

# Stage 2: Runtime image
FROM python:3.11-slim
WORKDIR /app
COPY --from=builder /app/dist/*.whl ./
RUN pip install *.whl &amp;amp;&amp;amp; rm *.whl
COPY --from=builder /app/src ./src
EXPOSE 5000
CMD ["python", "-m", "flask", "run", "--host=0.0.0.0"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Advanced Multi-Stage Patterns
&lt;/h4&gt;

&lt;h5&gt;
  
  
  The Testing Stage Pattern
&lt;/h5&gt;

&lt;p&gt;Want to run tests during your build but not include testing dependencies in your final image?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dockerfile
# Stage 1: Dependencies
FROM node:18-alpine AS deps
WORKDIR /app
COPY package*.json ./
RUN npm ci

# Stage 2: Testing
FROM deps AS testing
COPY . .
RUN npm test

# Stage 3: Build
FROM deps AS builder
COPY . .
RUN npm run build

# Stage 4: Production
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can then build with: &lt;code&gt;docker build --target testing .&lt;/code&gt; to run tests, or without the target to get the production image.&lt;/p&gt;

&lt;h4&gt;
  
  
  The Development vs Production Pattern
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dockerfile
# Base stage with common dependencies
FROM node:18-alpine AS base
WORKDIR /app
COPY package*.json ./

# Development stage
FROM base AS development
RUN npm install
COPY . .
EXPOSE 3000
CMD ["npm", "run", "dev"]

# Production build stage
FROM base AS builder
RUN npm ci --only=production
COPY . .
RUN npm run build

# Production runtime stage
FROM nginx:alpine AS production
COPY --from=builder /app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Build for development: &lt;code&gt;docker build --target development -t myapp:dev .&lt;/code&gt;&lt;br&gt;
Build for production: &lt;code&gt;docker build --target production -t myapp:prod .&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Best Practices: Making Multi-Stage Builds Sing
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Order Matters - Cache Like a Pro
Put the least frequently changing layers first:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dockerfile
# Good: Dependencies change less frequently than source code
COPY package*.json ./
RUN npm install
COPY . .

# Bad: This invalidates cache for every source code change
COPY . .
RUN npm install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Use Specific Base Images
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dockerfile
# Good: Explicit and smaller
FROM node:18-alpine AS builder

# Bad: Unpredictable and potentially larger
FROM node AS builder
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Clean Up in the Same Layer
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dockerfile
# Good: Cleanup in same layer
RUN apt-get update &amp;amp;&amp;amp; \
    apt-get install -y build-essential &amp;amp;&amp;amp; \
    npm install &amp;amp;&amp;amp; \
    apt-get remove -y build-essential &amp;amp;&amp;amp; \
    apt-get autoremove -y &amp;amp;&amp;amp; \
    rm -rf /var/lib/apt/lists/*

# Bad: Each RUN creates a layer
RUN apt-get update
RUN apt-get install -y build-essential
RUN npm install
RUN apt-get remove -y build-essential

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Use .dockerignore
Create a &lt;code&gt;.dockerignore&lt;/code&gt; file to prevent unnecessary files from being sent to the Docker daemon:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;node_modules
npm-debug.log
.git
.gitignore
README.md
.env
coverage
.nyc_output
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Common Pitfalls and How to Avoid Them
&lt;/h4&gt;

&lt;h5&gt;
  
  
  Pitfall 1: Copying Unnecessary Files Between Stages
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dockerfile
# Bad: Copying everything
COPY --from=builder /app /app

# Good: Being selective
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/package.json ./
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Pitfall 2: Not Using Build Arguments Effectively
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dockerfile
FROM node:18-alpine AS base
ARG NODE_ENV=production
ENV NODE_ENV=$NODE_ENV

FROM base AS development
# Development-specific setup

FROM base AS production
# Production-specific setup
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Build with: &lt;code&gt;docker build --build-arg NODE_ENV=development --target development .&lt;/code&gt;&lt;/p&gt;

&lt;h5&gt;
  
  
  Pitfall 3: Ignoring Security in Multi-Stage Builds
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dockerfile
# Good: Using non-root user
FROM alpine:latest
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001
COPY --from=builder --chown=nextjs:nodejs /app/build ./build
USER nextjs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  The Bottom Line
&lt;/h4&gt;

&lt;p&gt;Multi-stage builds aren't just about smaller images (though that 99% size reduction is pretty sweet). They're about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Faster deployments: Smaller images mean faster pushes and pulls&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Lower costs: Less storage, less bandwidth, less money&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Better security: Fewer tools in production mean fewer attack vectors&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cleaner architecture: Separation of build and runtime concerns&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Multi-stage builds transform Docker from a somewhat clunky virtualization tool into a precision instrument for creating exactly the runtime environment your application needs – nothing more, nothing less.&lt;br&gt;
The next time you're writing a Dockerfile, ask yourself: "What does my application actually need to run in production?" Chances are, it's a lot less than what you're currently shipping. Multi-stage builds help you ship exactly that – and your deployment pipeline will thank you for it.&lt;br&gt;
Remember: In the world of containers, less is definitely more. Your future self (and your infrastructure bill) will thank you for making the switch to multi-stage builds.&lt;/p&gt;

</description>
      <category>docker</category>
      <category>devops</category>
      <category>programming</category>
      <category>cloud</category>
    </item>
    <item>
      <title>Nginx for Beginners</title>
      <dc:creator>Oluwajubelo</dc:creator>
      <pubDate>Mon, 19 May 2025 10:35:50 +0000</pubDate>
      <link>https://dev.to/oluwajubelo1/nginx-for-beginners-480d</link>
      <guid>https://dev.to/oluwajubelo1/nginx-for-beginners-480d</guid>
      <description>&lt;h3&gt;
  
  
  What is Nginx?
&lt;/h3&gt;

&lt;p&gt;Nginx (pronounced "Engine-X") is a powerful, open-source web server software that can also function as a reverse proxy, load balancer, and HTTP cache. It’s known for its high performance, stability, and low resource usage, making it a popular choice for hosting websites and web applications.&lt;/p&gt;

&lt;h4&gt;
  
  
  Why Use Nginx?
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Speed:&lt;/strong&gt; Nginx is designed to handle many simultaneous connections efficiently.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Scalability:&lt;/strong&gt; It can manage high-traffic websites with ease.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Flexibility:&lt;/strong&gt; Works as a web server, reverse proxy, or load balancer.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Simplicity:&lt;/strong&gt; Configuration files are straightforward and easy to understand.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Community:&lt;/strong&gt; A large community and plenty of documentation are available.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Basic Concepts
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Web Server
&lt;/h4&gt;

&lt;p&gt;Nginx serves static content (like HTML, CSS, and images) to users’ browsers. It can also handle dynamic content by passing requests to application servers (e.g., those running PHP, Python, or Node.js).&lt;/p&gt;

&lt;h4&gt;
  
  
  Reverse Proxy
&lt;/h4&gt;

&lt;p&gt;As a reverse proxy, Nginx forwards client requests to backend servers, distributing the load and improving security by hiding the backend infrastructure.&lt;/p&gt;

&lt;h4&gt;
  
  
  Load Balancer
&lt;/h4&gt;

&lt;p&gt;Nginx can distribute incoming traffic across multiple servers to prevent any single server from becoming overwhelmed, ensuring reliability.&lt;/p&gt;

&lt;h4&gt;
  
  
  Configuration
&lt;/h4&gt;

&lt;p&gt;Nginx uses a simple, text-based configuration file (usually &lt;code&gt;nginx.conf&lt;/code&gt;) to define how it handles requests. This file is typically located in &lt;code&gt;/etc/nginx/&lt;/code&gt; on Linux systems.&lt;/p&gt;

&lt;h3&gt;
  
  
  Getting Started with Nginx
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Installation
&lt;/h4&gt;

&lt;p&gt;Here’s how to install Nginx on a Linux system (Ubuntu/Debian):&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Update the package list:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  2. Install Nginx:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt install nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  3. Start Nginx and enable it to run on boot:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo systemctl start nginx
sudo systemctl enable nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  4. Verify Nginx is running by visiting &lt;code&gt;http://your_server_ip&lt;/code&gt; in a browser. You should see the default Nginx welcome page.
&lt;/h4&gt;

&lt;h3&gt;
  
  
  Basic Configuration
&lt;/h3&gt;

&lt;p&gt;The main configuration file is &lt;code&gt;/etc/nginx/nginx.conf&lt;/code&gt;. A simple configuration might look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http {
    server {
        listen 80;
        server_name example.com;

        location / {
            root /var/www/html;
            index index.html;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;listen 80&lt;/code&gt;: Nginx listens for HTTP requests on port 80.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;server_name&lt;/code&gt;: Specifies the domain name (e.g., example.com).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;location /&lt;/code&gt;: Defines how to handle requests to the root URL.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;root&lt;/code&gt;: Sets the directory where website files are stored.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;index&lt;/code&gt;: Specifies the default file to serve (e.g., &lt;code&gt;index.html&lt;/code&gt;).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Serving a Simple Website
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. Create a directory for your website:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo mkdir -p /var/www/mywebsite
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  2. Create a basic &lt;code&gt;index.html&lt;/code&gt; file:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;echo "&amp;lt;h1&amp;gt;Hello from Nginx!&amp;lt;/h1&amp;gt;" | sudo tee /var/www/mywebsite/index.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  3. Update the Nginx configuration (&lt;code&gt;/etc/nginx/sites-available/mywebsite&lt;/code&gt;):
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;server {
    listen 80;
    server_name mywebsite.com;

    root /var/www/mywebsite;
    index index.html;

    location / {
        try_files $uri $uri/ /index.html;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  4. Enable the site by linking it to &lt;code&gt;sites-enabled&lt;/code&gt;:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo ln -s /etc/nginx/sites-available/mywebsite /etc/nginx/sites-enabled/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  5. Test the configuration for errors:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo nginx -t 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  6. Reload Nginx to apply changes:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo systemctl reload nginx 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  7. Visit &lt;code&gt;http://your_server_ip&lt;/code&gt; to see your “Hello from Nginx!” page.
&lt;/h4&gt;

&lt;h3&gt;
  
  
  Common Commands
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Start Nginx: &lt;code&gt;sudo systemctl start nginx&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Stop Nginx: &lt;code&gt;sudo systemctl stop nginx&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Restart Nginx: &lt;code&gt;sudo systemctl restart nginx&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Reload Configuration: &lt;code&gt;sudo systemctl reload nginx&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Check Status: &lt;code&gt;sudo systemctl status nginx&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Test Configuration: &lt;code&gt;sudo nginx -t&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>nginx</category>
      <category>ubuntu</category>
      <category>devops</category>
      <category>programming</category>
    </item>
    <item>
      <title>Laravel Queues for Beginners 🚀</title>
      <dc:creator>Oluwajubelo</dc:creator>
      <pubDate>Wed, 19 Mar 2025 09:16:23 +0000</pubDate>
      <link>https://dev.to/oluwajubelo1/laravel-queues-for-beginners-57ch</link>
      <guid>https://dev.to/oluwajubelo1/laravel-queues-for-beginners-57ch</guid>
      <description>&lt;p&gt;Laravel queues allow you to handle time-consuming tasks asynchronously, meaning they run in the background without slowing down your main application. This is especially useful for tasks like sending emails, processing file uploads, or handling large database operations.&lt;/p&gt;

&lt;h3&gt;
  
  
  📌 Why Use Queues?
&lt;/h3&gt;

&lt;h5&gt;
  
  
  1. &lt;strong&gt;Improves Performance&lt;/strong&gt;
&lt;/h5&gt;

&lt;p&gt;Your application doesn’t have to wait for tasks like email sending &lt;br&gt;
   to complete before responding.&lt;/p&gt;
&lt;h5&gt;
  
  
  2. &lt;strong&gt;Enhances User Experience&lt;/strong&gt;
&lt;/h5&gt;

&lt;p&gt;Users get immediate responses while tasks run in the background. &lt;/p&gt;
&lt;h5&gt;
  
  
  3. &lt;strong&gt;Efficient Resource Management&lt;/strong&gt;
&lt;/h5&gt;

&lt;p&gt;Heavy tasks can be processed separately, reducing the risk of timeouts. &lt;/p&gt;
&lt;h3&gt;
  
  
  🛠 Setting Up Laravel Queues
&lt;/h3&gt;

&lt;p&gt;By default, Laravel comes with a queue system that supports different queue drivers like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;sync&lt;/code&gt; (Runs jobs immediately, no real queue)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;database&lt;/code&gt; (Stores jobs in a database table)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;redis&lt;/code&gt; (High-performance queue storage)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;sqs&lt;/code&gt; (Amazon SQS)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;1️⃣ Configure the Queue Driver&lt;br&gt;
Open your &lt;code&gt;.env&lt;/code&gt; file and set the queue driver:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;QUEUE_CONNECTION=database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For Redis:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;QUEUE_CONNECTION=redis
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2️⃣ Create a Queue Job&lt;br&gt;
Run the Artisan command to generate a job:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;php artisan make:job SendWelcomeEmail
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates a job file in &lt;code&gt;app/Jobs/SendWelcomeEmail.php&lt;/code&gt;. Inside the &lt;code&gt;handle()&lt;/code&gt; method, you define what the job should do.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;namespace App\Jobs;

use App\Mail\WelcomeMail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Mail;

class SendWelcomeEmail implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    protected $user;

    public function __construct($user)
    {
        $this-&amp;gt;user = $user;
    }

    public function handle()
    {
        Mail::to($this-&amp;gt;user-&amp;gt;email)-&amp;gt;send(new WelcomeMail($this-&amp;gt;user));
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;📝 Key Points:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;ShouldQueue&lt;/code&gt; tells Laravel to process this job asynchronously.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;handle()&lt;/code&gt; contains the logic for sending the email.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;3️⃣ Dispatching a Job&lt;br&gt;
You can dispatch the job from anywhere in your application:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dispatch(new SendWelcomeEmail($user));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or use the &lt;code&gt;dispatch()&lt;/code&gt; helper:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SendWelcomeEmail::dispatch($user);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a delay:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SendWelcomeEmail::dispatch($user)-&amp;gt;delay(now()-&amp;gt;addMinutes(5));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4️⃣ Processing the Queue&lt;br&gt;
Before running jobs, you must start the queue worker:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;php artisan queue:work
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will continuously process new jobs in the queue.&lt;/p&gt;

&lt;p&gt;For database queues, you need to create the table:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;php artisan queue:table
php artisan migrate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want the worker to restart automatically after crashes, use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;php artisan queue:restart
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🔧 Queue Management Tips&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Retry Failed Jobs – If a job fails, you can retry it:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;php artisan queue:retry all
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Monitor Jobs – Use Horizon for Redis-based queues:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;php artisan horizon
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🎯 Conclusion&lt;br&gt;
Laravel queues make your application faster and more responsive by handling heavy tasks in the background. Start simple with database queues, then move to Redis or SQS for better scalability.&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>queue</category>
      <category>beginners</category>
      <category>php</category>
    </item>
    <item>
      <title>Understanding Cron Jobs in Laravel</title>
      <dc:creator>Oluwajubelo</dc:creator>
      <pubDate>Tue, 11 Mar 2025 15:42:23 +0000</pubDate>
      <link>https://dev.to/oluwajubelo1/understanding-cron-jobs-in-laravel-1oig</link>
      <guid>https://dev.to/oluwajubelo1/understanding-cron-jobs-in-laravel-1oig</guid>
      <description>&lt;p&gt;Imagine you own a poultry farm 🐔, and every morning at exactly 6 AM, you need to feed your chickens automatically. You don’t want to wake up early every day to do it manually. So, you buy an automatic feeder that dispenses food at 6 AM on its own.&lt;/p&gt;

&lt;p&gt;In Laravel, a cron job is like your automatic feeder. It allows you to schedule tasks that should run automatically at a specific time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why Do You Need a Cron Job?&lt;/strong&gt;&lt;br&gt;
Let's say you are running an e-commerce website 🛒, and you want to send a reminder email to customers every day at 9 AM about items left in their cart. Instead of sending these emails manually, you can create a Laravel cron job that handles it automatically.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to Set Up a Cron Job in Laravel&lt;/strong&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Step 1: Create a Laravel Command
&lt;/h4&gt;

&lt;p&gt;Laravel provides a way to define scheduled tasks using artisan commands. To create a new command, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;php artisan make:command SendCartReminderEmails
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will generate a file inside &lt;code&gt;app/Console/Commands/ named SendCartReminderEmails.php&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 2: Define the Command’s Logic
&lt;/h4&gt;

&lt;p&gt;Open the file &lt;code&gt;app/Console/Commands/SendCartReminderEmails.php&lt;/code&gt;, and you will see a &lt;code&gt;handle()&lt;/code&gt; method. This is where you define what should happen when the command runs.&lt;/p&gt;

&lt;p&gt;Modify the &lt;code&gt;handle()&lt;/code&gt; method like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use App\Models\User;
use App\Mail\CartReminderMail;
use Illuminate\Support\Facades\Mail;

class SendCartReminderEmails extends Command
{
    protected $signature = 'email:cart-reminder'; // Command name
    protected $description = 'Send reminder emails to users about items in their cart';

    public function __construct()
    {
        parent::__construct();
    }

    public function handle()
    {
        $users = User::whereHas('cart')-&amp;gt;get(); // Get users with items in their cart

        foreach ($users as $user) {
            Mail::to($user-&amp;gt;email)-&amp;gt;send(new CartReminderMail($user));
        }

        $this-&amp;gt;info('Cart reminder emails sent successfully!');
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Step 3: Schedule the Command in Kernel
&lt;/h4&gt;

&lt;p&gt;Now that we have our command, we need to tell Laravel when it should run.&lt;/p&gt;

&lt;p&gt;Open &lt;code&gt;app/Console/Kernel.php&lt;/code&gt; and inside the &lt;code&gt;schedule()&lt;/code&gt; method, add:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;protected function schedule(Schedule $schedule)
{
    $schedule-&amp;gt;command('email:cart-reminder')-&amp;gt;dailyAt('09:00'); // Runs every day at 9 AM
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here are other ways you can schedule a job:&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%2Fh4iz2k2q0e6g8rwj6yxy.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%2Fh4iz2k2q0e6g8rwj6yxy.png" alt="Schedule Expression" width="800" height="290"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 4: Register Laravel's Scheduler in Crontab
&lt;/h4&gt;

&lt;p&gt;Laravel’s scheduler does not run on its own. You need to register it in your server’s crontab (a list of scheduled tasks for Linux).&lt;/p&gt;

&lt;p&gt;Run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;crontab -e
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then add this line at the bottom:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;* * * * * php /path-to-your-project/artisan schedule:run &amp;gt;&amp;gt; /dev/null 2&amp;gt;&amp;amp;1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🔹 Explanation:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;* * * * *&lt;/code&gt; → Runs the Laravel scheduler every minute&lt;br&gt;
&lt;code&gt;php /path-to-your-project/artisan schedule:run&lt;/code&gt; → Runs Laravel's scheduled tasks&lt;br&gt;
&lt;code&gt;&amp;gt;&amp;gt; /dev/null 2&amp;gt;&amp;amp;1&lt;/code&gt; → Hides output (optional)&lt;/p&gt;
&lt;h4&gt;
  
  
  Step 5: Test the Cron Job Manually
&lt;/h4&gt;

&lt;p&gt;Before waiting for it to run automatically, you can test it by running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;php artisan schedule:run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If everything is set up correctly, Laravel will execute the job immediately.&lt;/p&gt;

&lt;h3&gt;
  
  
  Final Thoughts
&lt;/h3&gt;

&lt;p&gt;Just like how your automatic chicken feeder makes your life easier, cron jobs in Laravel help automate repetitive tasks like sending emails, clearing old records, or updating reports.&lt;/p&gt;

&lt;p&gt;So now, instead of manually reminding users about their abandoned carts, your Laravel application will automatically do it for you every morning at 9 AM—just like clockwork! 🕘🔔&lt;/p&gt;

&lt;p&gt;Would you like help setting up cron jobs for other use cases? 😊&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>cronjob</category>
      <category>programming</category>
    </item>
    <item>
      <title>Strategies for Optimizing MySQL Database Performance: A Case Study of Class54</title>
      <dc:creator>Oluwajubelo</dc:creator>
      <pubDate>Wed, 19 Feb 2025 09:09:32 +0000</pubDate>
      <link>https://dev.to/oluwajubelo1/strategies-for-optimizing-mysql-database-performance-a-case-study-of-class54-2mhh</link>
      <guid>https://dev.to/oluwajubelo1/strategies-for-optimizing-mysql-database-performance-a-case-study-of-class54-2mhh</guid>
      <description>&lt;p&gt;Optimizing Class54 Database to Handle Hundreds of Thousands of Records Without Latency&lt;/p&gt;

&lt;p&gt;Managing a database to handle extensive data processing efficiently can be a daunting task, especially when dealing with hundreds of thousands of records. This was precisely the challenge we faced with the Class54 database, which served as the backbone of our application. Its inefficiencies in handling large data sets led to significant latency issues, hampering performance and user experience. Here, I will share how we identified the problems, implemented solutions, and achieved optimal performance for our system.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Problem&lt;/strong&gt;&lt;br&gt;
Class54, a test preparation platform, provides resources for major Nigerian exams, including JAMB, WAEC, and POST-UTME of 36 major Nigerian schools. The platform hosts JAMB past questions from the year 2000 to 2024 and WAEC past questions from the same range. Initially designed to support a modest number of users, the platform grew exponentially, and so did the database’s workload. The core database, built on MySQL, started experiencing severe performance degradation when processing larger volumes of data. Tasks like fetching records for analytical dashboards, generating reports, or executing bulk updates took an unacceptably long time to complete.&lt;/p&gt;

&lt;p&gt;The following symptoms were observed:&lt;/p&gt;

&lt;h5&gt;
  
  
  1. Slow Query Execution:
&lt;/h5&gt;

&lt;p&gt;Some queries took several seconds or even minutes to execute.&lt;/p&gt;

&lt;h5&gt;
  
  
  2. High CPU Utilization:
&lt;/h5&gt;

&lt;p&gt;The database server frequently reached its CPU usage limits during peak hours.&lt;/p&gt;

&lt;h5&gt;
  
  
  3. Locking and Deadlocks:
&lt;/h5&gt;

&lt;p&gt;Concurrent operations led to frequent table locking, delaying processes and sometimes causing application crashes.&lt;/p&gt;

&lt;h5&gt;
  
  
  4. Inefficient Indexing:
&lt;/h5&gt;

&lt;p&gt;Tables had either too many indexes or poorly optimized ones, leading to increased storage usage and query latency.&lt;/p&gt;

&lt;h5&gt;
  
  
  5. Scalability Issues:
&lt;/h5&gt;

&lt;p&gt;The current design could not efficiently scale to handle the growing dataset without considerable cost.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Diagnosis&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;To address the issue, a thorough analysis of the database was conducted. This involved:&lt;/p&gt;

&lt;h5&gt;
  
  
  1. Query Profiling:
&lt;/h5&gt;

&lt;p&gt;Using MySQL’s EXPLAIN and SHOW PROFILE commands, we identified slow-performing queries and analyzed their execution plans.&lt;/p&gt;

&lt;h5&gt;
  
  
  2. Schema Review:
&lt;/h5&gt;

&lt;p&gt;A detailed review of the database schema highlighted unnecessary indexes, redundant columns, and inefficient table designs.&lt;/p&gt;

&lt;h5&gt;
  
  
  3. Workload Analysis:
&lt;/h5&gt;

&lt;p&gt;Tools like MySQL Workbench and monitoring utilities (such as Prometheus and Grafana) were used to analyze the workload patterns and identify bottlenecks.&lt;/p&gt;

&lt;h5&gt;
  
  
  4. Concurrency Testing:
&lt;/h5&gt;

&lt;p&gt;Simulated concurrent user interactions helped uncover locking issues and inefficiencies in handling parallel requests.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The Solution&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Armed with insights from our analysis, we implemented the following strategies to optimize the Class54 database:&lt;/p&gt;

&lt;h5&gt;
  
  
  1. &lt;strong&gt;Index Optimization&lt;/strong&gt;
&lt;/h5&gt;

&lt;p&gt;Indexes are vital for speeding up queries, but poorly designed indexes can be counterproductive. We:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Removed redundant and unused indexes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Created composite indexes to optimize queries filtering on multiple &lt;br&gt;
columns.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Reordered columns in indexes to match query patterns, ensuring &lt;br&gt;
maximum efficiency.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;
  
  
  2. &lt;strong&gt;Database Normalization and Denormalization&lt;/strong&gt;
&lt;/h5&gt;

&lt;p&gt;While normalization ensures data consistency, over-normalization can lead to excessive joins, slowing down queries. We:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Normalized tables to reduce redundancy where feasible.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Denormalized heavily accessed tables by introducing summary tables for frequently aggregated data, reducing join operations.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;
  
  
  3. &lt;strong&gt;Query Optimization&lt;/strong&gt;
&lt;/h5&gt;

&lt;p&gt;We rewrote inefficient queries and:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Replaced &lt;code&gt;SELECT *&lt;/code&gt; with explicit column selection to minimize data &lt;br&gt;
transfer.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Used batch processing for bulk operations to avoid locking large &lt;br&gt;
datasets.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Introduced pagination for fetching records in chunks rather than &lt;br&gt;
loading everything at once.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;
  
  
  4. &lt;strong&gt;Partitioning Large Tables&lt;/strong&gt;
&lt;/h5&gt;

&lt;p&gt;To manage large tables efficiently, we implemented horizontal partitioning:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Split large tables into smaller, more manageable partitions based &lt;br&gt;
on logical divisions (e.g., date ranges or user regions).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Queries were adjusted to target specific partitions, significantly &lt;br&gt;
reducing scan times.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;
  
  
  5. &lt;strong&gt;Caching Frequently Accessed Data&lt;/strong&gt;
&lt;/h5&gt;

&lt;p&gt;To reduce the load on the database:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Implemented an in-memory cache using Redis for frequently accessed, &lt;br&gt;
read-heavy data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Used query caching for recurring analytical queries, significantly &lt;br&gt;
speeding up response times.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;
  
  
  6. &lt;strong&gt;Connection Pooling and Load Balancing&lt;/strong&gt;
&lt;/h5&gt;

&lt;p&gt;Efficient connection management was ensured by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Implementing connection pooling to reuse database connections, &lt;br&gt;
reducing overhead from frequent opening and closing of connections.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Setting up read replicas for load balancing, directing read-heavy &lt;br&gt;
operations to replicas while keeping writes on the primary node.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;
  
  
  7. &lt;strong&gt;Migration to a Cloud-Native Database Architecture&lt;/strong&gt;
&lt;/h5&gt;

&lt;p&gt;To future-proof the system:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Migrated the database to a cloud-native managed service, taking &lt;br&gt;
advantage of features like auto-scaling and read replicas.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Introduced a data warehouse for heavy analytical workloads, &lt;br&gt;
separating transactional and analytical processing.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Results&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;After these optimizations, the Class54 database achieved the following improvements:&lt;/p&gt;

&lt;h5&gt;
  
  
  1. Reduced Query Latency:
&lt;/h5&gt;

&lt;p&gt;Average query execution time dropped from 10-15 seconds to under 200 milliseconds for most queries.&lt;/p&gt;

&lt;h5&gt;
  
  
  2. Improved Scalability:
&lt;/h5&gt;

&lt;p&gt;The database comfortably handled peak loads with over 500,000&lt;br&gt;
records, and its architecture allowed seamless scaling as data&lt;br&gt;
volumes grew.&lt;/p&gt;

&lt;h5&gt;
  
  
  3. Lower CPU Usage:
&lt;/h5&gt;

&lt;p&gt;Optimized queries and indexing significantly reduced CPU utilization, freeing up resources for other processes.&lt;/p&gt;

&lt;h5&gt;
  
  
  4. Enhanced User Experience:
&lt;/h5&gt;

&lt;p&gt;Faster query responses and smoother application performance led to increased user satisfaction and retention.&lt;/p&gt;

&lt;h5&gt;
  
  
  5. Significant Cost Reduction:
&lt;/h5&gt;

&lt;p&gt;Beyond the performance gains, these optimizations also translated into tangible cost savings. For instance, optimizing the student code generation function, which previously relied on inefficient &lt;code&gt;parent::pluck('student_code')&lt;/code&gt; calls, drastically reduced the load on our Digital Ocean droplets. This single improvement, combined with the other database optimizations, allowed us to downsize our droplet configuration, resulting in a substantial reduction in our monthly infrastructure expenses. This demonstrates our commitment to both performance and cost-efficiency.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Lessons Learned&lt;/strong&gt;
&lt;/h3&gt;

&lt;h5&gt;
  
  
  1. Proactive Monitoring:
&lt;/h5&gt;

&lt;p&gt;Regularly monitoring and profiling database performance can help identify issues before they escalate.&lt;/p&gt;

&lt;h5&gt;
  
  
  2. Iterative Optimization:
&lt;/h5&gt;

&lt;p&gt;Database optimization is an ongoing process that evolves with application requirements.&lt;/p&gt;

&lt;h5&gt;
  
  
  3. Balancing Normalization and Denormalization:
&lt;/h5&gt;

&lt;p&gt;Striking the right balance is crucial for maintaining data integrity and performance.&lt;/p&gt;

&lt;h5&gt;
  
  
  4. Investing in Automation:
&lt;/h5&gt;

&lt;p&gt;Using automated tools for indexing suggestions and query optimization can save considerable time and effort.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Optimizing the Class54 database was a challenging but rewarding experience. By combining careful analysis, strategic indexing, query optimization, and leveraging cloud-native solutions, we transformed the database into a high-performing, scalable component of our platform. These lessons and approaches can be applied to other database systems facing similar challenges, ensuring efficient handling of large datasets without compromising performance.&lt;/p&gt;

</description>
      <category>database</category>
      <category>mysql</category>
      <category>optimization</category>
      <category>latency</category>
    </item>
    <item>
      <title>Taming Entropy in GoLang Codebases</title>
      <dc:creator>Oluwajubelo</dc:creator>
      <pubDate>Thu, 13 Feb 2025 12:51:26 +0000</pubDate>
      <link>https://dev.to/oluwajubelo1/taming-entropy-in-golang-codebases-4oj6</link>
      <guid>https://dev.to/oluwajubelo1/taming-entropy-in-golang-codebases-4oj6</guid>
      <description>&lt;p&gt;&lt;strong&gt;What is Entropy?&lt;/strong&gt;&lt;br&gt;
Entropy at its core is the degree of how "chaotic" or "unorganized" a system is, therefore, the higher the entropy, the higher the chaos and disorder.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is Entropy in Software Design?&lt;/strong&gt;&lt;br&gt;
In the context of software development, &lt;strong&gt;entropy refers to the gradual accumulation of disorder and complexity within a codebase or system over time&lt;/strong&gt;. The disorder arises for severa factors which will include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Ad hoc changes&lt;/strong&gt;: Unplanned or poorly thought-out modifications.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Poor coding practices&lt;/strong&gt;: Inconsistent styles, lack of documentation, and absence of meaningful structure.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Complexity Creep&lt;/strong&gt;: As systems evolve, dependencies, edge cases, and special requirements add layers of complexity.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Lack of testing&lt;/strong&gt;: Bugs accumulate due to untested or poorly maintained code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Technical debt&lt;/strong&gt;: Quick fixes and shortcuts taken to meet deadlines lead to degraded code quality.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Team scaling&lt;/strong&gt;: Larger teams may lead to inconsistent approaches and styles if not governed by strong guidelines.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Organic Growth&lt;/strong&gt;: Codebases often grow organically, with features layered over existing code rather than planned holistically.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Lack of Standards&lt;/strong&gt;: Without coding guidelines or architectural principles, individual developers may implement solutions inconsistently.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Neglected Maintenance&lt;/strong&gt;: Over time, code that isn't refactored or reviewed tends to degrade.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Over time, high entropy in a software system can manifest as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Hard-to-read and poorly structured code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Increased likelihood of bugs and regressions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Difficulty in onboarding new developers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Longer development and debugging cycles.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Scalability issues and reduced performance.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The Impact of Entropy in Software Design&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Reduced Agility&lt;/strong&gt;: Adding new features becomes increasingly challenging due to the tangled codebase&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Higher Costs&lt;/strong&gt;: Debugging, refactoring, and scaling a disorganized system require significant resources.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Team Frustration&lt;/strong&gt;: Developers may feel demotivated working in a chaotic environment.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;System Instability&lt;/strong&gt;: Frequent bugs and downtime in production systems.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;How can we manage and reduce Entropy in our codebases?&lt;/strong&gt;&lt;br&gt;
We need to adopt strategies that maintain order and consistency, and these might include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Adhering to Coding Standards&lt;/strong&gt;: Use tools like linters, formatters, and style guides.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Implementing Clear Architecture&lt;/strong&gt;: Modular and well-defined components reduce interdependence.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Regular Refactoring&lt;/strong&gt;: Continuously improve code quality to adapt to new requirements without introducing chaos.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Testing&lt;/strong&gt;: Comprehensive testing prevents regressions and provides a safety net for changes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Documentation&lt;/strong&gt;: Clear documentation reduces uncertainty for future contributors.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now let’s talk about how to apply these strategies in Go codebases to enable us tame the chaos proactively.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. &lt;strong&gt;The Foundation: Coding Standards&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Why it matters&lt;/strong&gt;: Uniform coding practices make a codebase &lt;br&gt;
 predictable and easier to read.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Tools&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; gofmt: The gofmt package is used for automatic formatting of 
the codebase, this makes it such that all collaborators have 
a consistently formatted code, increasing readability. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Before gofmt:&lt;/p&gt;


&lt;/li&gt;

&lt;/ul&gt;

&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%2Fi28nh6p2xzi6an2qdaem.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%2Fi28nh6p2xzi6an2qdaem.png" alt="Before gofmt" width="800" height="336"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After gofmt:&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%2Fkzcgu7zm2f7ahc961do1.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%2Fkzcgu7zm2f7ahc961do1.png" alt="After gofmt" width="800" height="354"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;golint: provides feedback on Go code, focusing on the style and 
  best practices rather than functional correctness or runtime 
  behavior. It flags potential issues that deviates from Go's 
  conventions.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2. &lt;strong&gt;Organizing Packages and Code&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The problem&lt;/strong&gt;: Spaghetti package structures increase coupling and reduce maintainability.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Emphasize clear, single-responsibility packages.&lt;/li&gt;
&lt;li&gt;Use meaningful directory names and adhere to Go's "package-first" 
approach.&lt;/li&gt;
&lt;li&gt;Avoid circular dependencies by thinking in terms of layers or 
domains.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Most modern Go codebase use the hexagonal architecture, which encourages several patterns to make maintainability and scalability easier. I attempts to solve very common issues experienced by Go developers.&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. &lt;strong&gt;Interface-Driven Design&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Concept&lt;/strong&gt;: Define behaviors with interfaces and let &lt;br&gt;
implementations evolve independently.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Benefits&lt;/strong&gt;:&lt;br&gt;
  Easier testing with mock interfaces.&lt;br&gt;
  Decouples high-level modules from low-level details.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Example&lt;/strong&gt;: A Storage interface and its implementations &lt;br&gt;
(Cloudinary, Aws S3, etc.).&lt;/p&gt;&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%2Fim2f8n18x9etjazay389.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%2Fim2f8n18x9etjazay389.png" alt="Interface-Driven Design" width="800" height="85"&gt;&lt;/a&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%2F2j65iiffjgom6l7l3crd.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%2F2j65iiffjgom6l7l3crd.png" alt="Interface-Driven Design" width="800" height="216"&gt;&lt;/a&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%2Fn9a8wc4m55qgxk49fcqj.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%2Fn9a8wc4m55qgxk49fcqj.png" alt="Interface-Driven Design" width="800" height="213"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  4. &lt;strong&gt;Dependency Injection Done Right&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;What is it?&lt;/strong&gt; Injecting dependencies instead of hard-coding them &lt;br&gt;
to make components reusable and testable.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Approaches in Go&lt;/strong&gt;:&lt;br&gt;
  Constructor injection.&lt;br&gt;
  Use DI libraries sparingly (e.g., Uber’s fx).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Example&lt;/strong&gt;: Injecting the storage interface we created earlier &lt;br&gt;
into a file uploader service. This makes it possible for any of the &lt;br&gt;
storage interface implementations to be used in the UploadFile &lt;br&gt;
function&lt;/p&gt;&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%2Fkaa5wnmx9a4h4m15u4gr.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%2Fkaa5wnmx9a4h4m15u4gr.png" alt="Dependency Injection" width="800" height="756"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  5. &lt;strong&gt;Testing as a First-Class Citizen&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The importance of tests&lt;/strong&gt;: Tests document your code, validate &lt;br&gt;
behavior, and prevent regressions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Best Practices&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Write unit tests for core logic.&lt;/li&gt;
&lt;li&gt;Use table-driven tests to make them concise and readable.&lt;/li&gt;
&lt;li&gt;Incorporate integration tests for end-to-end behavior.&lt;/li&gt;
&lt;li&gt;Tools like &lt;code&gt;go&lt;/code&gt; test and &lt;code&gt;mockgen&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;strong&gt;Example&lt;/strong&gt;: Using mockgen to generate a mock for our storage &lt;br&gt;&lt;br&gt;
service, then using the mocked storage in our test.&lt;/p&gt;&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%2Fps26ol7n9cg3of35ci6v.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%2Fps26ol7n9cg3of35ci6v.png" alt="Testing" width="800" height="641"&gt;&lt;/a&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%2Fmj64778t43dmjft6j4rt.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%2Fmj64778t43dmjft6j4rt.png" alt="Testing" width="800" height="391"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Key Takeaways:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Consistent Coding&lt;/strong&gt;: Use gofmt and golint to enforce coding &lt;br&gt;
standards.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Clear Structure&lt;/strong&gt;: Organise packages logically to reduce &lt;br&gt;
complexity.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Interface-Driven Design&lt;/strong&gt;: Decouple components with small &lt;br&gt;
interfaces.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Dependency Injection&lt;/strong&gt;: Pass dependencies explicitly to improve &lt;br&gt;
testability.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Comprehensive Testing&lt;/strong&gt;: Regularly test code to maintain its &lt;br&gt;
quality.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These principles, applied consistently, will help you keep your Go codebase organised, scalable, and chaos-free.&lt;/p&gt;

&lt;p&gt;Thank you for reading. Remember, reducing entropy is a continuous process. By applying these strategies, you can keep your Go codebase clean and maintainable over time🙂&lt;/p&gt;

</description>
      <category>go</category>
      <category>entropy</category>
      <category>programming</category>
      <category>backenddevelopment</category>
    </item>
    <item>
      <title>How to Install Composer</title>
      <dc:creator>Oluwajubelo</dc:creator>
      <pubDate>Mon, 27 Jan 2025 08:38:22 +0000</pubDate>
      <link>https://dev.to/oluwajubelo1/how-to-install-composer-113p</link>
      <guid>https://dev.to/oluwajubelo1/how-to-install-composer-113p</guid>
      <description>&lt;p&gt;Composer is a dependency management tool for PHP. It helps developers manage libraries and packages their projects depend on. Instead of manually downloading and updating third-party PHP libraries, Composer automates the process, ensuring your project gets the correct versions and updates when needed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why Use Composer?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Saves Time: It eliminates the need to manually download and integrate libraries.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ensures Compatibility: Handles dependency conflicts and ensures libraries work together.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Simplifies Updates: Allows you to easily update libraries when new versions are available.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Boosts Collaboration: Other developers on your team can simply run &lt;code&gt;composer install&lt;/code&gt; to get all dependencies defined in the &lt;code&gt;composer.json&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Install Composer on Windows&lt;/strong&gt;&lt;br&gt;
Step 1: Download Composer Installer&lt;/p&gt;
&lt;h2&gt;
  
  
  1. Go to the official Composer website:
&lt;/h2&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  https://getcomposer.org/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  2.
&lt;/h2&gt;

&lt;p&gt;Click on "Getting Started" and then download the "Composer-Setup.exe" file for Windows.&lt;/p&gt;

&lt;p&gt;Step 2: Run the Installer&lt;/p&gt;
&lt;h2&gt;
  
  
  1. Open the downloaded &lt;code&gt;Composer-Setup.exe&lt;/code&gt; file.
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Follow the installation wizard:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Choose PHP Executable&lt;/strong&gt;: Locate your &lt;code&gt;php.exe&lt;/code&gt; file. If PHP is &lt;br&gt;
installed and added to your PATH, the installer will detect it &lt;br&gt;
 automatically.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If PHP is not installed, download it from php.net or install &lt;br&gt;
tools like XAMPP or WAMP.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Select Installation Path&lt;/strong&gt;: Choose the folder where Composer &lt;br&gt;
 should be installed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Add Composer to PATH&lt;/strong&gt;: The installer will offer to add &lt;br&gt;
 Composer to your system's PATH automatically. Ensure this option &lt;br&gt;
 is selected.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Step 3: Verify the Installation&lt;/p&gt;
&lt;h2&gt;
  
  
  1. Open Command Prompt or PowerShell.
&lt;/h2&gt;
&lt;h2&gt;
  
  
  2. Type:
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;composer --version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;If Composer is installed successfully, it will display the version.&lt;/p&gt;

&lt;p&gt;Install Composer on macOS&lt;/p&gt;

&lt;p&gt;Step 1: Install Homebrew (Optional)&lt;/p&gt;

&lt;p&gt;If you don’t have Homebrew installed, you can install it first. Homebrew is a package manager for macOS.&lt;/p&gt;
&lt;h2&gt;
  
  
  1. Open the terminal and run:
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  2. Verify Homebrew installation:
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;brew --version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Step 2: Install Composer&lt;/p&gt;
&lt;h2&gt;
  
  
  1. Open the terminal and run the following commands to download
&lt;/h2&gt;

&lt;p&gt;and install Composer:&lt;br&gt;
   Step 2.1: Download Composer installer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 2.2: Verify the installer (optional):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;php -r "if (hash_file('sha384', 'composer-setup.php') === file_get_contents('https://composer.github.io/installer.sig')) { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 2.3: Install Composer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;php composer-setup.php
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 2.4: Remove the installer file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;php -r "unlink('composer-setup.php');"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Move the composer binary to make it globally accessible:
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo mv composer.phar /usr/local/bin/composer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 3: Verify the Installation&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open the terminal and type:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;composer --version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If Composer is installed successfully, it will display the version.&lt;/p&gt;

&lt;p&gt;Alternative (Using Homebrew)&lt;/p&gt;

&lt;p&gt;If you have Homebrew, you can install Composer directly:&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Run:
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;brew install composer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Verify the installation:
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;composer --version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>Functions in PHP</title>
      <dc:creator>Oluwajubelo</dc:creator>
      <pubDate>Wed, 22 Jan 2025 15:50:21 +0000</pubDate>
      <link>https://dev.to/oluwajubelo1/functions-in-php-58do</link>
      <guid>https://dev.to/oluwajubelo1/functions-in-php-58do</guid>
      <description>&lt;h1&gt;
  
  
  What is a Function in PHP?
&lt;/h1&gt;

&lt;p&gt;A function in PHP is a block of reusable code designed to perform a specific task. It allows for modular programming, improves code readability, and reduces repetition. Think of a function as a way to handle repetitive tasks efficiently. Instead of going through the hassle of rewriting the same code every time you need to perform a task, you create a function once and simply call it whenever needed, saving time and effort.&lt;/p&gt;

&lt;p&gt;Functions are generally categorized into user-defined functions and built-in functions. Here's a closer look at each type:&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Built-in Functions
&lt;/h2&gt;

&lt;p&gt;These are predefined functions provided by PHP. They are ready to use and cover a wide range of tasks, such as string manipulation, array handling, mathematical operations, and working with files.&lt;/p&gt;

&lt;h3&gt;
  
  
  Features:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;They come with PHP and require no additional coding.&lt;/li&gt;
&lt;li&gt;Highly optimized for performance.&lt;/li&gt;
&lt;li&gt;Wide variety available for almost every common task.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Examples:
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;a.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nb"&gt;strtoupper&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"hello"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Outputs: HELLO&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nb"&gt;strlen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"PHP"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Outputs: 3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. User-defined Functions
&lt;/h2&gt;

&lt;p&gt;These are functions created by developers to solve specific problems or perform custom tasks. They are especially useful for tasks that need to be repeated or require unique logic not covered by built-in functions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Features:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Written by the developer to meet specific needs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Improve code reusability and organization.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Can take parameters, return values, and include custom logic.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Examples:
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;a.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function isAdult($age) {
    return $age &amp;gt;= 18 ? "Adult" : "Minor";
}

echo isAdult(16); // Outputs: Minor

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;b.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function add($a, $b) {
    return $a + $b;
}

echo add(5, 10); // Outputs: 15

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

&lt;/div&gt;



&lt;p&gt;Best Practices When Writing Functions in PHP&lt;br&gt;
Writing clean, efficient, and reusable functions is crucial for creating maintainable and scalable code. Here are some best practices to follow:&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Choose Descriptive Names
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Function names should clearly indicate what the function does.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use camelCase or snake_case naming conventions consistently.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function calculateTotalPrice($items) {
    // Code here
}

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Keep Functions Small and Focused
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A function should perform one specific task.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If a function becomes too long or does too many things, consider &lt;br&gt;
breaking it into smaller functions.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function getUserData($userId) {
    // Fetch user data from the database
}

function validateUserData($userData) {
    // Validate the fetched data
}

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Use Parameters and Arguments Thoughtfully
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Pass parameters to functions instead of relying on global &lt;br&gt;
variables.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Set default values for optional parameters.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function sendEmail($recipient, $subject = "No Subject") {
    // Email sending logic
}

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. Return Values Instead of Printing Directly
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Avoid directly printing data inside a function. Instead, return the 
value and let the calling code handle output.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function calculateDiscount($price, $discount) {
    return $price - ($price * $discount / 100);
}

echo calculateDiscount(100, 10); // Outputs: 90

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  5. Avoid Hardcoding Values
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Use constants or configuration files instead of hardcoding values 
within a function.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;define("DEFAULT_DISCOUNT", 10);

function applyDiscount($price, $discount = DEFAULT_DISCOUNT) {
    return $price - ($price * $discount / 100);
}

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

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>Introduction to PHP</title>
      <dc:creator>Oluwajubelo</dc:creator>
      <pubDate>Mon, 13 Jan 2025 15:04:42 +0000</pubDate>
      <link>https://dev.to/oluwajubelo1/introduction-to-php-mn3</link>
      <guid>https://dev.to/oluwajubelo1/introduction-to-php-mn3</guid>
      <description>&lt;p&gt;I'll be writing about the series of events we're conducting in the TechHaven Mentorship Program for Backend Engineers here. This being the first week, we walked through how to install PHP and VSCode (Visual Studio Code) on Windows and macOS systems.&lt;/p&gt;

&lt;p&gt;For Windows Users&lt;br&gt;
&lt;strong&gt;Step 1: Download XAMPP&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Visit this website to download: &lt;a href="https://www.apachefriends.org" rel="noopener noreferrer"&gt;https://www.apachefriends.org&lt;/a&gt;. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Choose the XAMPP version that supports PHP 8.2. Look for entries &lt;br&gt;
like XAMPP for PHP 8.2.x.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click the download link for your preferred version (Windows).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Save the installer file to your computer.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Install XAMPP&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run the Installer: &lt;/li&gt;
&lt;li&gt;Navigate to the folder where you downloaded the 
XAMPP installer (e.g., xampp-windows-x64-8.2.x-installer.exe).&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Double-click the installer to start the setup process.&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Choose Installation Components:&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;During the setup wizard, select the components you want to install. By default, essential components like Apache, MySQL, PHP, and phpMyAdmin are selected. Ensure PHP and phpMyAdmin are checked.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click Next to proceed&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Select Installation Folder:&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Choose the folder where you want to install XAMPP (default is &lt;br&gt;
C:\xampp). You can change this if needed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click Next.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Start Installation:&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Click Next to confirm your choices and start the installation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Wait for the installation process to complete. This may take a few &lt;br&gt;
minutes. &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Finish Installation:&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Once the installation is done, you’ll see a confirmation screen. 
Check the box to launch the XAMPP Control Panel and click Finish.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Configure and Verify Installation&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open XAMPP Control Panel:&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Launch the XAMPP Control Panel from your Start Menu or the 
installation directory.&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Start Apache and MySQL:&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;In the control panel, click Start next to Apache and MySQL.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ensure both services turn green, indicating they’re running.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Verify PHP Version:&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Open a browser and navigate to &lt;a href="http://localhost/dashboard" rel="noopener noreferrer"&gt;http://localhost/dashboard&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To verify PHP 8.2 is installed, create a phpinfo.php file:&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Navigate to C:\xampp\htdocs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a new file named phpinfo.php and add the following &lt;br&gt;
 content:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php
    phpinfo();
 ?&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Open your browser and go to &lt;a href="http://localhost/phpinfo.php" rel="noopener noreferrer"&gt;http://localhost/phpinfo.php&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You should see PHP 8.2 listed in the output.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Add PHP to System PATH (Optional)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Access Environment Variables:&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Press &lt;code&gt;Win + S&lt;/code&gt;, type Environment Variables, and select Edit the system environment variables.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the System Properties window, click Environment Variables.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Add PHP Path:&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Under System Variables, find the &lt;code&gt;Path&lt;/code&gt; variable and click Edit.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click New and add the path to the PHP folder, e.g., &lt;code&gt;C:\xampp\php&lt;/code&gt;. &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Save Changes:&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Click OK to save and close all windows.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Restart your system and open your terminal, then type &lt;code&gt;php -v&lt;/code&gt; , you should see something like this as response&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PHP 8.2.0 (cli) (built: Nov 29 2023 12:00:00) ( ZTS Visual C++ 2019 x64 )
Copyright (c) The PHP Group
Zend Engine v4.2.0, Copyright (c) Zend Technologies

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

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;For MacOS users:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Older macOS versions (prior to macOS Monterey) include PHP by default. However, the version might be outdated. &lt;br&gt;
Checking if PHP is Installed: Open the Terminal (Command + Space, type Terminal, and hit Enter) and run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;php -v
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;If PHP is installed, this will show the PHP version.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If not, you’ll get a message like command not found.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If PHP is Not Installed&lt;br&gt;
If your Mac does not have PHP (common in newer macOS versions), you can easily install it using tools like Homebrew.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Installing PHP Using Homebrew&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install Homebrew (if not already installed): Open Terminal and run:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;Install PHP: Run the following command to install the latest version of PHP:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;brew install php 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;if you want to install a specific version of PHP, use this command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;brew install php@version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Verify Installation: After installation, verify the PHP version:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;php -v
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Add PHP to PATH (if needed): Homebrew automatically adds PHP to 
your PATH, but if it doesn't work, add the following line to your 
~/.zshrc file (for Zsh shell, default on macOS):
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; export PATH="/usr/local/opt/php@&amp;lt;version&amp;gt;/bin:$PATH"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then reload your shell configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;source ~/.zshrc  # or source ~/.bash_profile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;To install MySQL, follow commands below&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install the MySQL package:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;brew install mysql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;if you want to install a specific version of PHP, use this command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;brew install mysql@version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Once installation is complete, start the MySQL service:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;brew services start mysql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Verify MySQL Installation:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Check the MySQL version to confirm installation:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mysql --version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mysql  Ver 8.0.x for osx on x86_64 (Homebrew)

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

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Log in to MySQL as the root user:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mysql -u root -p
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Stop/Restart MySQL Service (Optional):&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;To stop the MySQL service:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;brew services stop mysql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;To restart the MySQL service:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;brew services restart mysql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Configure PATH (if necessary)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Add the MySQL binary to your PATH (if not automatically added). Open your shell configuration file (e.g., ~/.zshrc or ~/.bash_profile) and add:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export PATH="/usr/local/opt/mysql/bin:$PATH"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Reload the shell configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;source ~/.zshrc  # or source ~/.bash_profile

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;To Install VSCode on your system, kindly follow the steps below:&lt;/strong&gt;&lt;br&gt;
Step 1: Download the Installer&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Visit the &lt;a href="https://code.visualstudio.com/" rel="noopener noreferrer"&gt;official VS Code website.&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click the Download for Windows/MacOS button. This will download the appropriate installer for your system.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Step 2: Run the Installer&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Locate the downloaded file (e.g., VSCodeSetup-x64-.exe for windows users, .dmg file for macos users) and double-click to run it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Follow the installation wizard:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Accept the license agreement.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Choose the installation location (default is fine for most users).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Select additional options, such as:&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Adding VS Code to your system PATH (recommended).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Creating a desktop shortcut.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Step 3: Launch VS Code&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Once the installation is complete, open VS Code by clicking the shortcut or searching for "Visual Studio Code" in the Start menu.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;For MacOS users:&lt;/strong&gt;&lt;br&gt;
After downloading the &lt;code&gt;.dmg&lt;/code&gt; file&lt;br&gt;
Step 2: Install VS Code&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Open the downloaded &lt;code&gt;.dmg&lt;/code&gt; file.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Drag and drop the Visual Studio Code icon into the Applications folder.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Step 3: Add VS Code to PATH (Optional)&lt;br&gt;
To use VS Code from the terminal:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Open VS Code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Press &lt;code&gt;Cmd + Shift + P&lt;/code&gt; to open the Command Palette.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Type &lt;code&gt;Shell Command: Install 'code' command in PATH&lt;/code&gt; and select it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Restart your terminal and verify by typing:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;/div&gt;



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