<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[ScalableCode]]></title><description><![CDATA[Code that grows with your business]]></description><link>https://scalablecode.com/</link><image><url>https://scalablecode.com/favicon.png</url><title>ScalableCode</title><link>https://scalablecode.com/</link></image><generator>Ghost 5.25</generator><lastBuildDate>Wed, 18 Mar 2026 13:19:43 GMT</lastBuildDate><atom:link href="https://scalablecode.com/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Queues at scale: idempotency, retries, dead letters — a practical guide]]></title><description><![CDATA[A hands-on guide to building reliable queue systems in production: idempotency, smart retries, backoff strategies, and dead-letter queues—without duplicate jobs, retry storms, or hidden failures.]]></description><link>https://scalablecode.com/queues-at-scale-idempotency-retries-dead-letter-queues/</link><guid isPermaLink="false">69884433946dc804a5d8ca15</guid><category><![CDATA[Laravel]]></category><category><![CDATA[Queues]]></category><dc:creator><![CDATA[ScalableCode]]></dc:creator><pubDate>Sun, 08 Feb 2026 08:13:01 GMT</pubDate><media:content url="https://scalablecode.com/content/images/2026/02/queues-best-practices.png" medium="image"/><content:encoded><![CDATA[<img src="https://scalablecode.com/content/images/2026/02/queues-best-practices.png" alt="Queues at scale: idempotency, retries, dead letters &#x2014; a practical guide"><p></p><p><strong>Queues look simple until your system is under real load.</strong></p><p>At small scale, you can usually get away with:</p><ul><li>&#x201C;Just retry it&#x201D;</li><li>&#x201C;It probably won&#x2019;t run twice&#x201D;</li><li>&#x201C;We&#x2019;ll check logs if something breaks&#x201D;</li></ul><p>At scale, that mindset turns into:</p><ul><li>Duplicate emails sent to customers</li><li>Orders processed twice</li><li>Infinite retry loops burning CPU and money</li><li>Poison messages blocking entire queues</li></ul><p>This post is a <strong>practical guide</strong> to three concepts that make or break queue-based systems in production:</p><ul><li><strong>Idempotency</strong> (doing things safely more than once)</li><li><strong>Retries</strong> (when and how to retry without making things worse)</li><li><strong>Dead-letter queues</strong> (what to do when a message is truly broken)</li></ul><p>Examples are generic, but this applies directly to Laravel queues, SQS, RabbitMQ, Kafka consumers, etc.</p><hr><h2 id="1-first-assume-your-job-will-run-more-than-once">1. First: assume your job WILL run more than once</h2><p>If you take only one thing from this article, take this:</p><blockquote>At scale, <strong>every job must be safe to run multiple times</strong>.</blockquote><p>Why?</p><ul><li>Workers crash mid-job</li><li>Timeouts happen</li><li>Network calls fail after the remote side already processed the request</li><li>The queue system may redeliver the same message</li><li>You may manually retry jobs</li></ul><p>So you must design jobs to be <strong>idempotent</strong>.</p><hr><h2 id="2-idempotency-making-%E2%80%9Crun-twice%E2%80%9D-safe">2. Idempotency: making &#x201C;run twice&#x201D; safe</h2><p><strong>Idempotent</strong> means:</p><blockquote>Running the same job 1 time or 10 times produces the same final result.</blockquote><h3 id="%E2%9D%8C-bad-example-not-idempotent">&#x274C; Bad example (not idempotent)</h3><pre><code class="language-php">public function handle()
{
    Order::find($this-&gt;orderId)-&gt;markAsPaid();
    Invoice::createForOrder($this-&gt;orderId);
    Mail::to($user)-&gt;send(new OrderPaidMail());
}
</code></pre><p>If this runs twice:</p><ul><li>You may mark the order paid twice</li><li>You may create two invoices</li><li>You may send two emails &#x1F62C;</li></ul><h3 id="%E2%9C%85-better-guard-with-state">&#x2705; Better: guard with state</h3><pre><code class="language-php">public function handle()
{
    $order = Order::find($this-&gt;orderId);

    if ($order-&gt;status === &apos;paid&apos;) {
        return; // already processed, safe exit
    }

    DB::transaction(function () use ($order) {
        $order-&gt;markAsPaid();

        Invoice::firstOrCreate([
            &apos;order_id&apos; =&gt; $order-&gt;id,
        ]);

        Mail::to($order-&gt;user)-&gt;send(new OrderPaidMail());
    });
}
</code></pre><p>Key ideas:</p><ul><li><strong>Check current state first</strong></li><li><strong>Use unique constraints / firstOrCreate</strong></li><li><strong>Wrap critical changes in transactions</strong></li><li><strong>Design side effects to be deduplicated</strong></li></ul><h3 id="even-better-idempotency-keys">Even better: idempotency keys</h3><p>For external APIs or critical operations:</p><ul><li>Store a <strong>unique idempotency key</strong> (e.g. <code>event_id</code>, <code>message_id</code>)</li><li>Before processing, check if it was already handled</li><li>If yes &#x2192; exit safely</li></ul><p>This is <em>mandatory</em> when dealing with:</p><ul><li>Payments</li><li>Webhooks</li><li>Inventory changes</li><li>Email/SMS sending</li></ul><hr><h2 id="3-retries-when-%E2%80%9Cjust-retry%E2%80%9D-becomes-dangerous">3. Retries: when &#x201C;just retry&#x201D; becomes dangerous</h2><p>Retries are good. <strong>Blind retries are not.</strong></p><h3 id="the-3-types-of-failures">The 3 types of failures</h3><p><strong>Transient</strong> (good for retries)</p><ul><li>Network timeout</li><li>Temporary DB overload</li><li>3rd-party API hiccup</li></ul><p><strong>Persistent</strong> (retries will never fix it)</p><ul><li>Invalid payload</li><li>Missing database record</li><li>Business rule violation</li></ul><p><strong>Poison</strong> (breaks your worker every time)</p><ul><li>Bug in code</li><li>Unexpected data shape</li><li>Serialization issues</li></ul><p>If you retry everything blindly:</p><ul><li>You waste resources</li><li>You block queues</li><li>You hide real bugs</li><li>You create retry storms under load</li></ul><hr><h2 id="4-smart-retry-strategy">4. Smart retry strategy</h2><h3 id="1-limit-retries">1) Limit retries</h3><p>Always cap retries:</p><ul><li>Laravel: <code>$tries = 5</code></li><li>SQS / RabbitMQ: max receive count</li><li>Kafka: max attempts or backoff strategy</li></ul><p>After N attempts &#x2192; <strong>stop</strong> and move to DLQ.</p><hr><h3 id="2-use-backoff-very-important">2) Use backoff (very important)</h3><p>Instead of retrying immediately:</p><ul><li>10s &#x2192; 30s &#x2192; 2m &#x2192; 10m &#x2192; 1h</li></ul><p>This:</p><ul><li>Reduces pressure on dependencies</li><li>Avoids retry storms</li><li>Gives time for transient issues to recover</li></ul><p>In Laravel:</p><pre><code class="language-php">public function backoff()
{
    return [10, 30, 120, 600];
}
</code></pre><hr><h3 id="3-classify-errors">3) Classify errors</h3><p>Inside your job:</p><pre><code class="language-php">try {
    $this-&gt;callExternalApi();
} catch (TemporaryNetworkException $e) {
    throw $e; // retry
} catch (InvalidPayloadException $e) {
    $this-&gt;fail($e); // do NOT retry
}
</code></pre><p>Rule of thumb:</p><ul><li><strong>Transient error</strong> &#x2192; retry</li><li><strong>Logic/data error</strong> &#x2192; fail fast &#x2192; DLQ</li></ul><hr><h2 id="5-dead-letter-queues-your-safety-net">5. Dead-letter queues: your safety net</h2><p>A <strong>Dead-Letter Queue (DLQ)</strong> is where messages go when:</p><ul><li>They exceeded max retries</li><li>They are explicitly marked as failed</li><li>They keep crashing workers</li></ul><p>This is not a graveyard. It&#x2019;s a <strong>debugging tool</strong>.</p><h3 id="what-should-you-do-with-dlq-messages">What should you do with DLQ messages?</h3><ul><li>Log them with full context</li><li>Alert when DLQ rate increases</li></ul><p>Build a small admin tool to:</p><ul><li>Inspect payload</li><li>See error reason</li><li>Replay the job after fixing the issue</li></ul><h3 id="common-dlq-causes-in-real-systems">Common DLQ causes in real systems</h3><ul><li>Code deployed that can&#x2019;t handle older messages</li><li>Data shape changed</li><li>Missing foreign keys</li><li>Assumptions that were never true in production</li></ul><p>If you don&#x2019;t have DLQs:</p><blockquote>You&#x2019;re either losing data silently or blocking your queues without knowing.</blockquote><hr><h2 id="6-the-%E2%80%9Cproduction-grade%E2%80%9D-checklist">6. The &#x201C;production-grade&#x201D; checklist</h2><p>If your queue system does all of this, you&#x2019;re in good shape:</p><ul><li>&#x2705; Jobs are idempotent</li><li>&#x2705; Side effects are deduplicated</li><li>&#x2705; Retries are capped</li><li>&#x2705; Retries use backoff</li><li>&#x2705; Transient vs permanent errors are distinguished</li><li>&#x2705; Dead-letter queue is enabled</li><li>&#x2705; DLQ is monitored</li><li>&#x2705; You can replay failed jobs safely</li></ul><hr><h2 id="7-the-uncomfortable-truth">7. The uncomfortable truth</h2><blockquote>Most queue bugs only appear under load, partial failures, or bad data.</blockquote><p>That&#x2019;s why:</p><ul><li>Local tests pass</li><li>Staging looks fine</li><li>Production explodes at 10&#xD7; traffic</li></ul><p>Designing for <strong>retries, duplicates, and failures</strong> is not &#x201C;over-engineering&#x201D;.<br>It&#x2019;s the difference between a system that degrades gracefully and one that wakes you up at 3am.</p><hr><h2 id="8-final-thought">8. Final thought</h2><p>Queues don&#x2019;t make systems reliable.</p><p><strong>Defensive design does.</strong></p><p>If you want queues that scale:</p><ul><li>Assume duplication</li><li>Expect failure</li><li>Design for recovery, not perfection</li></ul>]]></content:encoded></item><item><title><![CDATA[The Pros and Cons of Implementing Polymorphic Relationships in SQL Databases]]></title><description><![CDATA[Polymorphic relationships offer flexibility in databases but risk data integrity and increase query complexity. Use them sparingly, with checks for integrity and consider alternatives to maintain performance and integrity.]]></description><link>https://scalablecode.com/the-pros-and-cons-of-implementing-polymorphic-relationships-in-sql-databases/</link><guid isPermaLink="false">65ce55325d5ae404a459332d</guid><category><![CDATA[MySql]]></category><category><![CDATA[Laravel]]></category><dc:creator><![CDATA[ScalableCode]]></dc:creator><pubDate>Thu, 15 Feb 2024 18:23:05 GMT</pubDate><media:content url="https://scalablecode.com/content/images/2024/02/The-Pros-and-Cons-of-Implementing-Polymorphic-Relationships-in-SQL-Databases.webp" medium="image"/><content:encoded><![CDATA[<img src="https://scalablecode.com/content/images/2024/02/The-Pros-and-Cons-of-Implementing-Polymorphic-Relationships-in-SQL-Databases.webp" alt="The Pros and Cons of Implementing Polymorphic Relationships in SQL Databases"><p>Polymorphic relationships in relational databases offer flexibility in modeling various types of associations within a single framework. However, whether they are a good idea depends on the specific requirements of your application and the trade-offs you are willing to make. Here are some considerations:</p><h3 id="advantages">Advantages</h3><ol><li><strong>Flexibility</strong>: Polymorphic relationships allow a single foreign key to reference multiple types of entities, making it easier to associate a wide variety of objects with a single entity.</li><li><strong>Simplification</strong>: They can simplify the schema by reducing the number of tables and relationships needed to represent complex associations between different entity types.</li></ol><h3 id="disadvantages">Disadvantages</h3><ol><li><strong>Referential Integrity</strong>: Traditional relational databases like MySQL enforce referential integrity through foreign keys, which isn&apos;t directly possible with polymorphic relationships. This means you can&apos;t rely on the database to automatically ensure that all references are valid, leading to potential data integrity issues.</li><li><strong>Query Complexity</strong>: Queries involving polymorphic associations can become more complex and less intuitive, especially when you need to join multiple tables based on the type of the associated entity.</li><li><strong>Performance</strong>: The need to filter by an additional column (<code>entity_type</code> in many implementations) and potentially join multiple tables to retrieve all related entities can lead to performance issues, especially as the dataset grows.</li><li><strong>Database Features Limitation</strong>: You might not be able to use some database features, such as cascading deletes, as straightforwardly as you would with standard foreign key relationships.</li></ol><h3 id="best-practices">Best Practices</h3><ul><li><strong>Use Sparingly</strong>: Consider polymorphic relationships only when you have a clear use case that benefits significantly from this flexibility, and the disadvantages are manageable within the context of your application.</li><li><strong>Application-level Integrity</strong>: Implement checks and balances in your application code to ensure data integrity, given the database won&apos;t enforce referential integrity for polymorphic relationships.</li><li><strong>Documentation</strong>: Thoroughly document your database schema and the logic behind any polymorphic relationships to ensure that future developers can understand and maintain the system effectively.</li><li><strong>Alternative Approaches</strong>: Evaluate alternative data modeling techniques, such as table inheritance (using a separate table for each entity type but with a common structure) or entity-attribute-value (EAV) models, to see if they might meet your needs with fewer trade-offs.</li></ul><p>In summary, while polymorphic relationships can be powerful for certain use cases, they come with significant considerations that might make them less suitable for traditional relational database systems, especially when data integrity and performance are top priorities.</p>]]></content:encoded></item><item><title><![CDATA[Quick Guide: Testing MySQL Connection Without the MySQL CLI]]></title><description><![CDATA[Explore various methods to test MySQL connections directly from the command line. From telnet to Python scripts, ensure your database is reachable.]]></description><link>https://scalablecode.com/quick-guide-testing-mysql-connection-without-the-mysql-cli/</link><guid isPermaLink="false">6527956a5d5ae404a459331e</guid><category><![CDATA[MySql]]></category><dc:creator><![CDATA[ScalableCode]]></dc:creator><pubDate>Thu, 12 Oct 2023 06:48:51 GMT</pubDate><content:encoded><![CDATA[<p>If you don&apos;t have the MySQL client installed but you have access to the command line, you can use other tools to test the MySQL connection. Here are a few methods:</p><p><strong>Using <code>telnet</code></strong>:<br>If you know the server&apos;s IP and port (default is 3306 for MySQL), you can try to establish a connection using <code>telnet</code>.</p><pre><code class="language-bash">telnet [server_ip] [port]
</code></pre><p>For example:</p><pre><code class="language-bash">telnet 127.0.0.1 3306
</code></pre><p>If you&apos;re connected, you&apos;ll see some output from MySQL. If not, you&apos;ll get a connection error.</p><p><strong>Using <code>netcat</code> (<code>nc</code>)</strong>:<br>Similar to <code>telnet</code>, you can use <code>netcat</code> to check the connection.</p><pre><code class="language-bash">nc -zv [server_ip] [port]
</code></pre><p>For example:</p><pre><code class="language-bash">nc -zv 127.0.0.1 3306
</code></pre><p><strong>Using <code>curl</code></strong>:<br>This won&apos;t establish a proper MySQL connection, but it can tell you if the port is open and listening.</p><pre><code class="language-bash">curl -v telnet://[server_ip]:[port]
</code></pre><p>For example:</p><pre><code class="language-bash">curl -v telnet://127.0.0.1:3306
</code></pre><p><strong>Using PHP</strong>:<br>If you have PHP installed, you can use it to test the MySQL connection. Create a file named <code>test_mysql.php</code> with the following content:</p><pre><code class="language-php">&lt;?php
$servername = &quot;your_server_name&quot;;
$username = &quot;your_username&quot;;
$password = &quot;your_password&quot;;
$dbname = &quot;your_dbname&quot;; // Optional

// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);

// Check connection
if ($conn-&gt;connect_error) {
    die(&quot;Connection failed: &quot; . $conn-&gt;connect_error);
} 
echo &quot;Connected successfully&quot;;
?&gt;
</code></pre><p>Run the script using:</p><pre><code class="language-bash">php test_mysql.php
</code></pre><p><strong>Using Python</strong>:<br>If you have Python and the <code>mysql-connector-python</code> package installed, you can use it to test the MySQL connection. Here&apos;s a simple script:</p><pre><code class="language-python">import mysql.connector

try:
    connection = mysql.connector.connect(
        host=&apos;your_server_name&apos;,
        user=&apos;your_username&apos;,
        password=&apos;your_password&apos;,
        database=&apos;your_dbname&apos;  # Optional
    )
    if connection.is_connected():
        print(&apos;Connected to MySQL database&apos;)
    connection.close()
except Exception as e:
    print(f&quot;Error: {e}&quot;)
</code></pre><p>Remember to replace placeholders like <code>your_server_name</code>, <code>your_username</code>, etc., with your actual MySQL credentials.</p>]]></content:encoded></item><item><title><![CDATA[Securely Connect to Amazon RDS using SSH Tunneling and Table Plus]]></title><description><![CDATA[Discover how to securely connect to an Amazon RDS instance without exposing it to the public. This guide walks you through SSH tunneling, setting up a bastion host, and ensuring optimal security practices.]]></description><link>https://scalablecode.com/tunnel-connec-to-amazon-rds-database-using-table-plus/</link><guid isPermaLink="false">65266c305d5ae404a45932e7</guid><category><![CDATA[MySql]]></category><category><![CDATA[AWS]]></category><category><![CDATA[RDS]]></category><dc:creator><![CDATA[ScalableCode]]></dc:creator><pubDate>Wed, 11 Oct 2023 10:01:02 GMT</pubDate><content:encoded><![CDATA[<p>Creating a tunnel connection to an Amazon RDS instance is a common way to securely connect to a database without exposing it to the public internet. This is typically done using SSH tunneling. Here&apos;s a step-by-step guide on how to set up a tunnel connection to an Amazon RDS instance:</p><h3 id="prerequisites">Prerequisites:</h3><ol><li><strong>SSH Access</strong>: You need SSH access to an EC2 instance that has access to the RDS instance. This EC2 instance will act as a &quot;jump host&quot; or &quot;bastion host&quot;.</li><li><strong>SSH Client</strong>: You need an SSH client installed on your local machine. For Linux and macOS, this is typically available by default. For Windows, you can use tools like PuTTY.</li><li><strong>Database Client</strong>: You need a database client on your local machine to connect to the RDS instance through the tunnel.</li></ol><h3 id="steps">Steps:</h3><p><strong>Configure Security Groups</strong>:</p><ul><li>Ensure that the RDS instance&apos;s security group allows inbound connections from the EC2 instance (jump host).</li><li>Ensure that the EC2 instance&apos;s security group allows inbound SSH connections from your local machine&apos;s IP address.</li></ul><p><strong>Establish an SSH Tunnel</strong>:</p><ul><li>Open a terminal or command prompt.</li><li>Use the following command to establish an SSH tunnel <br><code>ssh -L local_port:rds_endpoint:rds_port ec2-user@ec2_instance_ip -i path_to_ec2_private_key</code></li><li><code>local_port</code>: A free port on your local machine (e.g., <code>8888</code>).</li><li><code>rds_endpoint</code>: The endpoint of your RDS instance <br>(e.g., <code>mydb-instance.123456789012.us-west-1.rds.amazonaws.com</code>).</li><li><code>rds_port</code>: The port on which your RDS instance is listening (e.g., <code>3306</code> for MySQL).</li><li><code>ec2_instance_ip</code>: The public IP address of your EC2 instance.</li><li><code>path_to_ec2_private_key</code>: The path to the private key file for your EC2 instance (e.g., <code>~/path/to/my-key.pem</code>).</li></ul><p><strong>Connect to RDS through the Tunnel</strong>:</p><ul><li>Now that the tunnel is established, you can use your database client to connect to the RDS instance as if it&apos;s running on <code>localhost</code> at the <code>local_port</code> you specified. </li><li>For example, if you&apos;re using MySQL, you can connect using <br><code>mysql -h 127.0.0.1 -P 8888 -u db_username -p</code></li><li>Using Table Plus:</li></ul><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://scalablecode.com/content/images/2023/10/table-plus-ssh-tunnel-connection.png" class="kg-image" alt loading="lazy" width="1224" height="1088" srcset="https://scalablecode.com/content/images/size/w600/2023/10/table-plus-ssh-tunnel-connection.png 600w, https://scalablecode.com/content/images/size/w1000/2023/10/table-plus-ssh-tunnel-connection.png 1000w, https://scalablecode.com/content/images/2023/10/table-plus-ssh-tunnel-connection.png 1224w" sizes="(min-width: 720px) 720px"><figcaption>Table plus connection</figcaption></figure><p><strong>Close the Tunnel</strong>:</p><ul><li>Once you&apos;re done with your database tasks, you can close the tunnel by pressing <code>CTRL+C</code> in the terminal where the SSH tunnel is running.</li></ul><h3 id="notes">Notes:</h3><ul><li>Always ensure that your EC2 and RDS instances have strict security group rules to minimize security risks.</li><li>Using a bastion host or jump host is a best practice to access resources in a private subnet, as it provides an additional layer of security.</li></ul>]]></content:encoded></item><item><title><![CDATA[Making the Right Tech Stack Choice for Your Business]]></title><description><![CDATA[Starting a new company or launching a new product? Choosing the right tech stack is crucial. Learn the 5 proven strategies for selecting the optimal tech stack for your startup, including considering your target market, analyzing the job market, scalability, costs and community.]]></description><link>https://scalablecode.com/making-the-right-tech-stack-choice-for-your-business/</link><guid isPermaLink="false">63c410525d5ae404a459324b</guid><category><![CDATA[Start-up]]></category><category><![CDATA[TechStack]]></category><dc:creator><![CDATA[ScalableCode]]></dc:creator><pubDate>Sun, 15 Jan 2023 15:04:02 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1602265585142-6b221b9b2c24?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDF8fHRlY2hub2xvZ3klMjBzdGFja3xlbnwwfHx8fDE2NzM3OTM3MTQ&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1602265585142-6b221b9b2c24?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDF8fHRlY2hub2xvZ3klMjBzdGFja3xlbnwwfHx8fDE2NzM3OTM3MTQ&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="Making the Right Tech Stack Choice for Your Business"><p>Starting a new company or launching a new product can be exciting, but it also comes with a lot of decisions to make. One of the most important decisions you&apos;ll need to make is what<strong> tech stack</strong> to use. The tech stack refers to the combination of programming languages, frameworks, and tools you&apos;ll use to build your product. Choosing the right tech stack can have a significant impact on the success of your company or product, so it&apos;s essential to approach this decision with care.</p><p>Here are five strategies you can use to choose the right tech stack for your start-up:</p><ol><li>Consider your target market: The first thing you need to consider when choosing a tech stack is your target market. For example, are you building a product for consumers or businesses? Will your product be used on mobile devices or desktop computers? The answers to these questions will help you narrow your options and choose a good-suited tech stack for your target market.</li><li>Look at the job market: The job market is another critical factor to consider when choosing a tech stack. You&apos;ll want to choose a tech stack that is in high demand so that you can find developers with the skills you need to build your product. Look at job postings in your area or online, and see which tech stacks are used most frequently.</li><li>Think about scalability: As your company or product grows, you&apos;ll need to be able to scale your tech stack to meet the increased demand. Consider the scalability of the different tech stacks you&apos;re considering, and choose one that can handle large amounts of traffic and data.</li><li>Consider the costs: Building a product or company can be expensive, so you&apos;ll want to be mindful of the costs associated with different tech stacks. For example, some tech stacks may require costly licenses, while others may be open-source and free to use. So make sure to factor in the costs when making your decision.</li><li>Look at the community: Finally, consider the community surrounding the tech stack you&apos;re considering. A strong community means that many people use and contribute to the stack, which can be a good indicator of its health and longevity and solutions to common problems already available and battle-tested. If you are developing a real product with strict deadlines, avoid novel tech stacks.</li></ol><p>Adding to all the above and unless you have really strict requirements (e.g. financial or healthcare industries), <strong>choose a tech stack that allows you to get to market as quickly as possible</strong>.</p><blockquote>Perfect products delivered past deadline kill companies faster than decent products delivered on-time. <br><strong>Tim Ferris</strong></blockquote><p>In conclusion, choosing the right tech stack for your start-up is crucial. By considering your target market, job market, scalability, costs and community, you can make an informed decision and select the tech stack that will help you achieve your goals and build a successful company or product.</p>]]></content:encoded></item><item><title><![CDATA[How to export large datasets to CSV in Laravel?]]></title><description><![CDATA[Exporting large datasets in Laravel & Laravel Livewire can be challenging, as you need to be mindful of memory limits and processing time.]]></description><link>https://scalablecode.com/how-to-export-large-datasets-to-excel-in-laravel/</link><guid isPermaLink="false">63b88a095d5ae404a45931a8</guid><category><![CDATA[Laravel]]></category><category><![CDATA[Scaling]]></category><category><![CDATA[Laravel Livewire]]></category><category><![CDATA[Exporting Data]]></category><dc:creator><![CDATA[ScalableCode]]></dc:creator><pubDate>Fri, 06 Jan 2023 21:39:00 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1529078155058-5d716f45d604?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDE0fHxzcHJlYWRzaGVldHxlbnwwfHx8fDE2NzMwNDEwNDE&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1529078155058-5d716f45d604?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDE0fHxzcHJlYWRzaGVldHxlbnwwfHx8fDE2NzMwNDEwNDE&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="How to export large datasets to CSV in Laravel?"><p>Exporting large datasets in Laravel can be challenging, as you need to be mindful of memory limits and processing time. </p><p>Have you seen this error message when exporting large datasets in Laravel?<br><em>Allowed memory size of 134217728 bytes exhausted (tried to allocate 20971520 bytes)</em></p><p>This was a problem I struggled with for a long time using the <em><strong><a href="https://laravel-excel.com/">Laravel Excel</a></strong></em> package until I found <em><strong><a href="https://github.com/spatie/simple-excel">spatie/simple-excel</a></strong></em>, which makes this very easy.</p><p>The example below will export a list of users into a CSV quickly and efficiently without <em>exhausting</em> the memory. I have used this method with over 200k records generating a CSV file of over 30MB in a few minutes.</p><p></p><pre><code class="language-php">&lt;?php

namespace App\Http\Controllers;

use App\User;
use Illuminate\Http\Request;
use Maatwebsite\Excel\Facades\Excel;
use Spatie\SimpleExcel\SimpleExcelWriter;

class UserExportController extends Controller
{
    public function export()
    {
        $writer = SimpleExcelWriter::streamDownload(&apos;users.csv&apos;);
        $query = User::orderBy(&apos;created_at&apos;);
        
        $i = 0;
        foreach ($query-&gt;lazy(1000) as $user) 
        {
            $writer-&gt;addRow($user-&gt;toArray());

            if ($i % 1000 === 0) {
                flush(); // Flush the buffer every 1000 rows
            }
            $i++;
        }

        return $writer-&gt;toBrowser();
    }
}</code></pre><p></p><h2 id="exporting-in-laravel-livewire">Exporting &#xA0;in Laravel Livewire</h2><p>The method mentioned above does not work in Laravel Livewire. I attempted several methods suggested on GitHub that were supposed to work, but none of them worked for me.</p><p>To resolve this issue, I created a new endpoint using a controller that is not a Livewire component and implemented the method above. The download button in the Livewire component now links to this endpoint, passing any required parameters, and the download starts immediately.</p><p>Check sample code below!</p><pre><code class="language-php">&lt;?php
// Route
Route::get(&apos;/campaigns/{campaignId}/recipients/download/{status?}&apos;, [&apos;as&apos; =&gt; &apos;uni.api.campaigns.recipients.download&apos;, &apos;uses&apos; =&gt; &apos;Uni\Api\Campaigns\CampaignRecipientsDownloadController@index&apos;]);</code></pre><pre><code class="language-php">&lt;?php
// Controller

namespace Papillon\Http\Controllers\Uni\Api\Campaigns;

use Illuminate\Support\Str;
use Papillon\Campaigns\Campaign;
use Papillon\Campaigns\CampaignReporting;
use Spatie\SimpleExcel\SimpleExcelWriter;

class CampaignRecipientsDownloadController
{
	protected $campaign;
	protected $status = null;

	public function index($campaignId, $status = null)
	{
		$this-&gt;campaign = Campaign::findOrFail($campaignId);
		$this-&gt;status = $status;

		$fileName = Str::slug($this-&gt;campaign-&gt;name) . &apos;-&apos; . $this-&gt;status . &apos;-&apos; . now()-&gt;format(&apos;Ymd_His&apos;) . &apos;.csv&apos;;
		$writer = SimpleExcelWriter::streamDownload($fileName);

		
		$i = 0;
		foreach ($this-&gt;getRecipientsList()-&gt;lazy(150) as $recipient) {
			$writer-&gt;addRow([
				&apos;id&apos; =&gt; $recipient-&gt;id,
				&apos;email&apos; =&gt; $recipient-&gt;email,
				&apos;first_name&apos; =&gt; $recipient-&gt;first_name,
				&apos;last_name&apos; =&gt; $recipient-&gt;last_name,
				&apos;job_title&apos; =&gt; $recipient-&gt;job_title,
				&apos;company&apos; =&gt; $recipient-&gt;company,
				&apos;country&apos; =&gt; $recipient-&gt;country,
				&apos;status&apos; =&gt; $recipient-&gt;status,
				&apos;opened&apos; =&gt; $recipient-&gt;opened ? &apos;Yes&apos; : &apos;No&apos;,
				&apos;clicked&apos; =&gt; $recipient-&gt;click_count
			]);

			if ($i % 1000 === 0) {
				flush(); // Flush the buffer every 1000 rows
			}
			$i++;
		}


		return $writer-&gt;toBrowser();
	}

	private function getRecipientsList()
	{
		return resolve(CampaignReporting::class)-&gt;getRecipientsList($this-&gt;campaign, true, true);
	}
}</code></pre><pre><code class="language-html">&lt;!-- Download button --&gt;
&lt;x-wave-toolbar.link
    icon-set=&quot;material-symbols&quot;
    icon=&quot;download&quot;
    x-tooltip=&quot;`Export recipients`&quot;
    :href=&quot;route(&apos;uni.api.campaigns.recipients.download&apos;, [$this-&gt;campaign-&gt;id, $this-&gt;recipientStatus])&quot;
&gt;&lt;/x-wave-toolbar.link&gt;</code></pre>]]></content:encoded></item><item><title><![CDATA[The Importance of Code Quality for Business Success]]></title><description><![CDATA[Every company relies on software to function effectively, whether a traditional business or a technology company. Code quality becomes increasingly crucial for a company's success as software continues to shape our world.]]></description><link>https://scalablecode.com/the-importance-of-code-quality-for-business-success/</link><guid isPermaLink="false">639629867e93de32c45e3627</guid><category><![CDATA[Scaling]]></category><category><![CDATA[Growth]]></category><dc:creator><![CDATA[ScalableCode]]></dc:creator><pubDate>Sat, 17 Dec 2022 13:40:00 GMT</pubDate><media:content url="https://scalablecode.com/content/images/2020/05/importance-of-code-1.png" medium="image"/><content:encoded><![CDATA[<img src="https://scalablecode.com/content/images/2020/05/importance-of-code-1.png" alt="The Importance of Code Quality for Business Success"><p><strong>Every company relies on software to function effectively, whether a traditional business or a technology company. Code quality becomes increasingly crucial for a company&apos;s success as software continues to shape our world.</strong></p><p>When I started programming 15 years ago, I thought the most important thing was that &#x201C;it worked&#x201D;. As I started working on projects for the long term, it was clear that was not the case.</p><blockquote>If you give me a program that works perfectly but is impossible to change, then it won&#x2019;t work when the requirements change, and I won&#x2019;t be able to make it work. Therefore the program will become useless. <br>If you give me a program that does not work but is easy to change, then I can make it work, and keep it working as requirements change. Therefore the program will remain continually useful. <br><em><strong>Robert C. Martin</strong></em></blockquote><p>Maintainable code is critical to the success of a product. Code that is easy to change allows the team to move faster and ship features quickly, which is a massive advantage. Software keeps getting more sophisticated, so it is imperative to implement best practices from day one to keep code clean and easy to maintain and extend.</p><p>There are many ways in which &#x201C;code quality&#x201D;, or lack thereof, affects your company:</p><h3 id="improved-maintainability">Improved maintainability</h3><p> Well-written and easy-to-understand code is much easier to maintain and modify over time, saving time and resources in the long run.</p><h3 id="better-collaboration">Better collaboration </h3><p>Code that is well-documented and follows established coding standards is easier for team members to work on together, improving collaboration and productivity.</p><h3 id="ability-to-retain-talented-programmers"><strong>Ability to retain talented programmers</strong></h3><p><em><em>Bad code</em></em> frustrates programmers because it does not allow them to be productive. Good programmers like to move quickly and confidently; if code does not allow them to, they leave. <em><em>Good code</em></em> allows programmers to be productive and fulfilled and, in turn, less likely to leave.</p><h3 id="being-able-to-change-quickly"><strong>Being able to change quickly</strong></h3><p><em><em>In software, as in life, the only constant is change</em></em>. <br>Code has a short lifetime; even successful products are continually changing.<br>Being able to change quickly is critical. Companies able to adapt quickly are the most likely to succeed in the short and long run.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://scalablecode.com/content/images/2020/05/Productivity-release.png" class="kg-image" alt="The Importance of Code Quality for Business Success" loading="lazy"><figcaption>Productivity by release with low-quality code. Tends to zero&#x2026;</figcaption></figure><h3 id="reduced-costs">Reduced costs</h3><p>Code that is of high quality is less likely to contain errors and defects, which can save time and resources that would be spent on fixing those issues.</p><h3 id="increased-reliability">Increased reliability</h3><p>High-quality code is more reliable, improving the overall reliability of a business&apos;s products or services.</p><h3 id="enhanced-security">Enhanced security</h3><p>Good code is less prone to bugs and more secure. Security breaches are very costly and damage the company&#x2019;s brand. This is especially important for businesses that handle sensitive information.</p><h3 id="improved-scalability">Improved scalability</h3><p>Code that is well-written and follows best practices is easier to scale and adapt to changing business needs, allowing businesses to grow and adapt more easily.<br></p><hr><p>Writing good code is hard; that is why good programmers are expensive. Football teams with bad players and companies with bad programmers lose too.</p><p>Be a craftsman. You will be pleased in the future and so will your company.</p>]]></content:encoded></item><item><title><![CDATA[If you don’t understand why accessibility is so important, please watch!]]></title><description><![CDATA[If you don’t understand (yet) why accessibility is so important, please watch this video of a blind person navigating through a website using a screen reader, it will change the way you write and structure HTML.]]></description><link>https://scalablecode.com/importance-of-accessibility/</link><guid isPermaLink="false">639629867e93de32c45e3621</guid><category><![CDATA[Accessibility]]></category><dc:creator><![CDATA[ScalableCode]]></dc:creator><pubDate>Wed, 14 Dec 2022 13:40:00 GMT</pubDate><media:content url="https://scalablecode.com/content/images/2020/05/accessibility-1.png" medium="image"/><content:encoded><![CDATA[<img src="https://scalablecode.com/content/images/2020/05/accessibility-1.png" alt="If you don&#x2019;t understand why accessibility is so important, please watch!"><p>If you don&#x2019;t understand (yet) why accessibility is so important, please watch this video of a blind person navigating through a website using a screen reader, it will change the way you write and structure HTML.</p><figure class="kg-card kg-embed-card kg-card-hascaption"><iframe width="480" height="270" src="https://www.youtube.com/embed/dEbl5jvLKGQ?feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe><figcaption>Screen Reader Demo for Digital Accessibility</figcaption></figure><blockquote>285 million people are estimated to be visually impaired worldwide: 39 million are blind and 246 have low vision.&#x201D; (see <a href="https://www.who.int/mediacentre/factsheets/fs282/en/">Visual impairment and blindness</a>).<br>World Health Organization</blockquote>]]></content:encoded></item><item><title><![CDATA[Testing Laravel apps with multiple domains]]></title><description><![CDATA[When testing Laravel applications that use multiple domains tests get a bit tricky. Find how how to test Laravel apps with multiple domains.]]></description><link>https://scalablecode.com/testing-laravel-apps-with-multiple-domains/</link><guid isPermaLink="false">639629867e93de32c45e3622</guid><category><![CDATA[Laravel]]></category><category><![CDATA[Testing]]></category><dc:creator><![CDATA[ScalableCode]]></dc:creator><pubDate>Sat, 10 Dec 2022 13:40:00 GMT</pubDate><media:content url="https://scalablecode.com/content/images/2022/12/laravel-mark-rgb-red.png" medium="image"/><content:encoded><![CDATA[<img src="https://scalablecode.com/content/images/2022/12/laravel-mark-rgb-red.png" alt="Testing Laravel apps with multiple domains"><p>When testing Laravel applications that use multiple domains tests get tricky. Imagine an application with the following structure:</p><ul><li>API: api.domain.com</li><li>Backend: manage.domain.com</li><li>Client domains: client1domain.com,client2domain.com, etc..</li></ul><pre><code class="language-PHP">Route::domain(config(&apos;app.domains.api&apos;))-&gt;group(function() {
  Route::get(&apos;/&apos;, &apos;Api\ApiIndexController@index&apos;)-&gt;as(&apos;api.index&apos;);
});

Route::domain(config(&apos;app.domains.backend&apos;))-&gt;group(function() {
  Route::get(&apos;/&apos;, &apos;Backend\BackendIndexController@index&apos;)-&gt;as(&apos;backend.index&apos;);
});

// fallback to client domains
Route::group(function() {
  Route::get(&apos;/&apos;, &apos;Sites\SitesIndexController@index&apos;)-&gt;as(&apos;site.index&apos;);
});</code></pre><p>Now let&#x2019;s see how we would go about testing the routes within each domain.</p><pre><code class="language-PHP">namespace Tests\Feature\Api;

use Tests\TestCase;

class ApiDomainTest extends TestCase
{
    function setUp(): void
    {
        parent::setUp();
        config([&apos;app.url&apos; =&gt; &quot;http://${config(&apos;app.domains.api&apos;)}&quot;]);
    }

    public function testApiIndex()
    {
        $response = $this-&gt;json(&apos;GET&apos;, route(&apos;api.index&apos;));
        $response-&gt;assertStatus(200)-&gt;assertSeeText(&apos;API index.&apos;);
    }
}</code></pre><pre><code class="language-PHP">namespace Tests\Feature\Backend;

use Tests\TestCase;

class BackendDomainTest extends TestCase
{
    function setUp(): void
    {
        parent::setUp();
        config([&apos;app.url&apos; =&gt; &quot;https://${config(&apos;app.domains.backend&apos;)}&quot;]);
    }

    public function testBackendApiIndex()
    {
        $response = $this-&gt;json(&apos;GET&apos;, route(&apos;backend.index&apos;));
        $response-&gt;assertStatus(200)-&gt;assertSeeText(&apos;Backend index.&apos;);
    }
}</code></pre><pre><code class="language-PHP">namespace Tests\Feature\Site;

use Tests\TestCase;

class SiteDomainsTest extends TestCase
{
    public function testClient1SiteIndex()
    {
        config([&apos;app.url&apos; =&gt; &quot;http://clientdomain1.com&quot;]);
        $response = $this-&gt;json(&apos;GET&apos;, route(&apos;site.index&apos;));
        $response-&gt;assertStatus(200)-&gt;assertSeeText(&apos;This is client site 1 index.&apos;);
    }

     public function testClient1SiteIndex()
    {
        config([&apos;app.url&apos; =&gt; &quot;http://clientdomain2.com&quot;]);
        $response = $this-&gt;json(&apos;GET&apos;, route(&apos;site.index&apos;));
        $response-&gt;assertStatus(200)-&gt;assertSeeText(&apos;This is client site 2 index.&apos;);
    }
}</code></pre>]]></content:encoded></item></channel></rss>