<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:media="http://search.yahoo.com/mrss/" >

<channel>
	<title>Marc Costea | Qilin.Cloud</title>
	<atom:link href="https://qilin.cloud/author/m-costea/feed/" rel="self" type="application/rss+xml" />
	<link>https://qilin.cloud</link>
	<description>Technology Platform for composable e-commerce</description>
	<lastBuildDate>Wed, 25 Mar 2026 16:34:43 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0</generator>

<image>
	<url>https://qilin.cloud/wp-content/uploads/2023/08/cropped-QilinCloud-Logo-32x32.png</url>
	<title>Marc Costea | Qilin.Cloud</title>
	<link>https://qilin.cloud</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Operational Control: Queue Storage, Credentials, and Advanced Routing in the Portal UI</title>
		<link>https://qilin.cloud/operational-control-queue-storage-credentials-advanced-routing-portal/</link>
		
		<dc:creator><![CDATA[Marc Costea]]></dc:creator>
		<pubDate>Sat, 28 Feb 2026 08:00:00 +0000</pubDate>
				<category><![CDATA[Product Updates]]></category>
		<category><![CDATA[credentials]]></category>
		<category><![CDATA[operations]]></category>
		<category><![CDATA[portal]]></category>
		<category><![CDATA[queue storage]]></category>
		<category><![CDATA[routing]]></category>
		<guid isPermaLink="false">https://qilin.cloud/?p=3751</guid>

					<description><![CDATA[<p>February’s update focuses on operational control: manage queue storages and credentials in the Portal UI, and configure advanced routing/processing primitives with more confidence and less JSON spelunking.</p>
<p>The post <a rel="nofollow" href="https://qilin.cloud/operational-control-queue-storage-credentials-advanced-routing-portal/">Operational Control: Queue Storage, Credentials, and Advanced Routing in the Portal UI</a> appeared first on <a rel="nofollow" href="https://qilin.cloud">Qilin.Cloud</a>.</p>
]]></description>
										<content:encoded><![CDATA[<div class="et_pb_section et_pb_section_0 et_section_regular" >
				
				
				
				
				
				
				<div class="et_pb_row et_pb_row_0">
				<div class="et_pb_column et_pb_column_4_4 et_pb_column_0  et_pb_css_mix_blend_mode_passthrough et-last-child">
				
				
				
				
				<div class="et_pb_module et_pb_text et_pb_text_0  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><p>A platform reaches a certain point where “features” aren’t the bottleneck anymore.</p>
<p>Operations is.</p>
<p>You can have the best pipeline logic in the world, but if teams can’t:</p>
<ul>
<li>manage credentials safely</li>
<li>inspect and control queue storages</li>
<li>configure routing logic without fear</li>
<li>iterate on pipelines without breaking running executions</li>
</ul>
<p>…then the platform becomes a black box again.</p>
<p>February’s update is about <strong>operational control &#8211; </strong>the unglamorous superpower that makes complex integrations run calmly for months.</p>
<p>This month we focused on expanding Portal UI capabilities around:</p>
<ul>
<li><strong>Queue Storage management</strong></li>
<li><strong>Credential management</strong></li>
<li><strong>Advanced processor configuration (switch-case, filtering, merge, loop, enrichment)</strong></li>
</ul>
<p>In other words: more knobs, fewer prayers.</p></div>
			</div>
			</div>
				
				
				
				
			</div><div class="et_pb_row et_pb_row_1">
				<div class="et_pb_column et_pb_column_4_4 et_pb_column_1  et_pb_css_mix_blend_mode_passthrough et-last-child">
				
				
				
				
				<div class="et_pb_module pac_divi_table_of_contents pac_divi_table_of_contents_0">
				
				
				
				
				
				
				<div class="et_pb_module_inner">
					
        <div class="pac_dtoc_main_container"
        data-allow_collapse_minimize="on"
        data-allow_collapse_minimize_tablet="on"
        data-allow_collapse_minimize_phone="on"
        data-ss="2000"
        data-sah="100"
        data-collapse_when_sticky="off"
        data-collapse_when_sticky_tablet="off"
        data-collapse_when_sticky_phone="off"
        data-skh="off"
        data-mtocai="off"
        data-mtocai_tablet="off"
        data-mtocai_phone="off"
        data-alh="off"
        data-ds="closed"
        data-dst="closed"
        data-dsp="closed">
            <div class="pac_dtoc_title_area click_on click_tablet_on click_phone_on">
                <div role="heading" aria-level="2" id="pac_dtocm_title" class="pac_dtoc_title">Table of Contents</div>
                
                <div class="pac_dtoc_icon_responsive">
                    <div class="pac_dtoc_opened_icon">2</div>
                    <div class="pac_dtoc_closed_icon">3</div>
                </div>
                
            </div>
            <div role="navigation" aria-labelledby="pac_dtocm_title" class="pac_dtoc_body_area inside">
                
                <div class='divi_table_of_contents' role="tree" ><ul class="pac_dtoc_heading_level_1" role="group" ><li class="pac_dtoc_li_heading_level_1" role="treeitem" ><div role="presentation" ><span data-href='#pac_remove_first_heading' data-hl='1'></span><a href='#pac_remove_first_heading' id='pac_remove_first_heading_toc_headding'>FirstHeading</a></div></li><ul class="pac_dtoc_heading_level_2" role="group" ><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#QueueStorageManagementbufferingyoucanoperatenotjustconfigure' data-hl='2'></span><a href='#QueueStorageManagementbufferingyoucanoperatenotjustconfigure' id='QueueStorageManagementbufferingyoucanoperatenotjustconfigure_toc_headding'>Queue Storage Management: buffering you can operate, not just configure</a></div></li><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#CredentialManagementstoptreatingsecretslikepipelinecode' data-hl='2'></span><a href='#CredentialManagementstoptreatingsecretslikepipelinecode' id='CredentialManagementstoptreatingsecretslikepipelinecode_toc_headding'>Credential Management: stop treating secrets like pipeline code</a></div></li><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#AdvancedroutingandtransformationnowUIfriendly' data-hl='2'></span><a href='#AdvancedroutingandtransformationnowUIfriendly' id='AdvancedroutingandtransformationnowUIfriendly_toc_headding'>Advanced routing and transformation—now UI-friendly</a></div></li><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#Fordevelopers' data-hl='2'></span><a href='#Fordevelopers' id='Fordevelopers_toc_headding'>For developers</a></div></li><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#Formerchantsagenciesandinvestors' data-hl='2'></span><a href='#Formerchantsagenciesandinvestors' id='Formerchantsagenciesandinvestors_toc_headding'>For merchants, agencies, and investors</a></div></li><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#Thedirectionisclear' data-hl='2'></span><a href='#Thedirectionisclear' id='Thedirectionisclear_toc_headding'>The direction is clear</a></div></li><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#Readytorunintegrationswithoutthedrama' data-hl='2'></span><a href='#Readytorunintegrationswithoutthedrama' id='Readytorunintegrationswithoutthedrama_toc_headding'>Ready to run integrations without the drama?</a></div></li></ul></div>
            </div>
        </div>
        
				</div>
			</div>
			</div>
				
				
				
				
			</div><div class="et_pb_row et_pb_row_6">
				<div class="et_pb_column et_pb_column_4_4 et_pb_column_6  et_pb_css_mix_blend_mode_passthrough et-last-child">
				
				
				
				
				<div class="et_pb_module et_pb_blurb et_pb_blurb_7  et_pb_text_align_left  et_pb_blurb_position_top et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_blurb_content">
					
					<div class="et_pb_blurb_container">
						<h2 class="et_pb_module_header"><span>Queue Storage Management: buffering you can operate, not just configure</span></h2>
						<div class="et_pb_blurb_description"><p>Queue Storage (QQS) is powerful, but only if you can manage it confidently.</p>
<p>Operational teams need to answer:</p>
<ul>
<li>Which queue storages exist for this subscription?</li>
<li>What are their durations and schedules?</li>
<li>Are items piling up?</li>
<li>Are batches being released as expected?</li>
<li>Can we adjust thresholds without breaking pipelines?</li>
</ul>
<p>Bringing QQS management into the Portal UI turns buffering from “a clever config” into “an operational tool”.</p>
<p>That matters a lot when you’re running high-volume offer or catalog syncs across multiple channels.</p></div>
					</div>
				</div>
			</div>
			</div>
				
				
				
				
			</div><div class="et_pb_row et_pb_row_7">
				<div class="et_pb_column et_pb_column_4_4 et_pb_column_7  et_pb_css_mix_blend_mode_passthrough et-last-child">
				
				
				
				
				<div class="et_pb_module et_pb_blurb et_pb_blurb_8  et_pb_text_align_left  et_pb_blurb_position_top et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_blurb_content">
					
					<div class="et_pb_blurb_container">
						<h2 class="et_pb_module_header"><span>Credential Management: stop treating secrets like pipeline code</span></h2>
						<div class="et_pb_blurb_description"><p>Credentials are not pipeline logic.</p>
<p>They’re security artifacts.</p>
<p>So the platform experience is moving toward a cleaner separation:</p>
<ul>
<li>pipeline definitions reference credentials by ID</li>
<li>credentials are managed centrally (create/update/rotate)</li>
<li>permissions control who can access or modify what</li>
</ul>
<p>When credential management is visible and structured, teams can:</p>
<ul>
<li>rotate keys without redeploying pipelines</li>
<li>separate agency responsibilities from merchant ownership</li>
<li>reduce “who still has the production token?” moments (which should not exist)</li>
</ul></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_accordion et_pb_accordion_1">
				
				
				
				
				<div class="et_pb_toggle et_pb_module et_pb_accordion_item et_pb_accordion_item_1  et_pb_toggle_open">
				
				
				
				
				<h5 class="et_pb_toggle_title"></h5>
				<div class="et_pb_toggle_content clearfix">We invite you to share your experiences and lessons learned with Qilin.Cloud’s innovative technology platform for composable e-commerce. Your story can inspire others and help the whole community to improve.</p>
<p>&nbsp;</p>
<h4><strong>Share your Qilin.Cloud Success Story</strong><br />
<span> </span></h4>
<div class="et_pb_button_module_wrapper et_pb_button_0_wrapper  et_pb_module "><a class="et_pb_button et_pb_button_0 et_pb_bg_layout_light" href="https://qilin.cloud/share-your-story/">Your Journey</a></div></div>
			</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_9  et_pb_text_align_left  et_pb_blurb_position_top et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_blurb_content">
					
					<div class="et_pb_blurb_container">
						<h2 class="et_pb_module_header"><span>Advanced routing and transformation—now UI-friendly</span></h2>
						<div class="et_pb_blurb_description"><p>As pipelines grow, they stop being linear.</p>
<p>They become decision trees:</p>
<ul>
<li>filter out invalid objects</li>
<li>route based on marketplace/storefront</li>
<li>switch-case based on complex conditions</li>
<li>merge parallel branches</li>
<li>loop through collections when needed</li>
<li>enrich objects with rule-based actions</li>
</ul>
<p>Qilin.Cloud has been building these primitives for a while.</p>
<p>February’s focus has been making them easier to configure and operate through the Portal UI, so teams can:</p>
<ul>
<li>build complex routing without hand-editing JSON</li>
<li>review logic visually</li>
<li>reduce configuration mistakes</li>
<li>onboard new team members faster</li>
</ul>
<p>This is how a platform stays usable as it gets more powerful.</p></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_10  et_pb_text_align_left  et_pb_blurb_position_top et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_blurb_content">
					
					<div class="et_pb_blurb_container">
						<h2 class="et_pb_module_header"><span>For developers</span></h2>
						<div class="et_pb_blurb_description"><p>Operational UI work might sound “non-technical”, but it’s actually developer leverage:</p>
<ul>
<li>fewer support tickets</li>
<li>fewer manual interventions</li>
<li>fewer misconfigurations</li>
<li>faster iteration cycles</li>
</ul>
<p>You spend less time being the “human control plane”.</p></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_11  et_pb_text_align_left  et_pb_blurb_position_top et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_blurb_content">
					
					<div class="et_pb_blurb_container">
						<h2 class="et_pb_module_header"><span>For merchants, agencies, and investors</span></h2>
						<div class="et_pb_blurb_description"><ul>
<li><strong>Merchants:</strong> more transparency and safer operation of pipelines in production.</li>
<li><strong>Agencies:</strong> easier delivery and maintenance; clearer boundaries of responsibility.</li>
<li><strong>Investors:</strong> this is maturity. Operational features reduce costs and unlock bigger customers with higher requirements.</li>
</ul></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_12  et_pb_text_align_left  et_pb_blurb_position_top et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_blurb_content">
					
					<div class="et_pb_blurb_container">
						<h2 class="et_pb_module_header"><span>The direction is clear</span></h2>
						<div class="et_pb_blurb_description"><p>The story from the past 18 months has been consistent:</p>
<ul>
<li>build strong pipeline primitives (filtering, enrichment, merge, buffering)</li>
<li>make them observable (tracking and status)</li>
<li>make them operable (UI control and safe recovery)</li>
</ul>
<p>That’s how platforms earn trust.</p></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_13  et_pb_text_align_left  et_pb_blurb_position_top et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_blurb_content">
					
					<div class="et_pb_blurb_container">
						<h2 class="et_pb_module_header"><span>Ready to run integrations without the drama?</span></h2>
						<div class="et_pb_blurb_description"><p>Complex commerce workflows will always have complexity.</p>
<p>The goal isn’t to pretend it’s simple.</p>
<p>The goal is to make complexity manageable &#8211; predictable, observable, and controllable.</p>
<p>That’s what February’s work is about. And it’s where Qilin.Cloud is heading.</p></div>
					</div>
				</div>
			</div>
			</div>
				
				
				
				
			</div>
				
				
			</div>
<p>The post <a rel="nofollow" href="https://qilin.cloud/operational-control-queue-storage-credentials-advanced-routing-portal/">Operational Control: Queue Storage, Credentials, and Advanced Routing in the Portal UI</a> appeared first on <a rel="nofollow" href="https://qilin.cloud">Qilin.Cloud</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>The Engine Tune-Up: Redis, MongoDB, and the Performance Foundations of Qilin.Cloud</title>
		<link>https://qilin.cloud/engine-tune-up-redis-mongodb-performance-foundations/</link>
		
		<dc:creator><![CDATA[Marc Costea]]></dc:creator>
		<pubDate>Tue, 31 Dec 2024 08:00:00 +0000</pubDate>
				<category><![CDATA[Product Updates]]></category>
		<category><![CDATA[caching]]></category>
		<category><![CDATA[mongodb]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[redis]]></category>
		<category><![CDATA[scaling]]></category>
		<guid isPermaLink="false">https://qilin.cloud/?p=3610</guid>

					<description><![CDATA[<p>December’s platform work focused on speed and stability: smarter caching, more predictable persistence, and the kind of infrastructure upgrades users feel even if they never see them.</p>
<p>The post <a rel="nofollow" href="https://qilin.cloud/engine-tune-up-redis-mongodb-performance-foundations/">The Engine Tune-Up: Redis, MongoDB, and the Performance Foundations of Qilin.Cloud</a> appeared first on <a rel="nofollow" href="https://qilin.cloud">Qilin.Cloud</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<div class="et_pb_section et_pb_section_1 et_section_regular" >
				
				
				
				
				
				
				<div class="et_pb_row et_pb_row_8">
				<div class="et_pb_column et_pb_column_4_4 et_pb_column_8  et_pb_css_mix_blend_mode_passthrough et-last-child">
				
				
				
				
				<div class="et_pb_module et_pb_text et_pb_text_2  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><p>If you’ve ever tuned a high-performance engine, you know the paradox:</p>
<p>The best upgrades are the ones nobody “sees”… <br />…and everyone <em>feels</em>.</p>
<p>December’s development work has been a classic engineering move: <strong>platform hardening</strong>.</p>
<p>Not a flashy new button. Not a marketing headline. <br />The kind of change experienced teams do because they’ve been burned before—and they refuse to be burned again.</p>
<p>This month, we’ve focused on two things:</p>
<ol>
<li><strong>Faster, more predictable data access</strong></li>
<li><strong>A smoother operational foundation for growth</strong></li>
</ol></div>
			</div>
			</div>
				
				
				
				
			</div><div class="et_pb_row et_pb_row_9">
				<div class="et_pb_column et_pb_column_4_4 et_pb_column_9  et_pb_css_mix_blend_mode_passthrough et-last-child">
				
				
				
				
				<div class="et_pb_module pac_divi_table_of_contents pac_divi_table_of_contents_1">
				
				
				
				
				
				
				<div class="et_pb_module_inner">
					
        <div class="pac_dtoc_main_container"
        data-allow_collapse_minimize="on"
        data-allow_collapse_minimize_tablet="on"
        data-allow_collapse_minimize_phone="on"
        data-ss="2000"
        data-sah="100"
        data-collapse_when_sticky="off"
        data-collapse_when_sticky_tablet="off"
        data-collapse_when_sticky_phone="off"
        data-skh="off"
        data-mtocai="off"
        data-mtocai_tablet="off"
        data-mtocai_phone="off"
        data-alh="off"
        data-ds="closed"
        data-dst="closed"
        data-dsp="closed">
            <div class="pac_dtoc_title_area click_on click_tablet_on click_phone_on">
                <div role="heading" aria-level="2" id="pac_dtocm_title" class="pac_dtoc_title">Table of Contents</div>
                
                <div class="pac_dtoc_icon_responsive">
                    <div class="pac_dtoc_opened_icon">2</div>
                    <div class="pac_dtoc_closed_icon">3</div>
                </div>
                
            </div>
            <div role="navigation" aria-labelledby="pac_dtocm_title" class="pac_dtoc_body_area inside">
                
                <div class='divi_table_of_contents' role="tree" ><ul class="pac_dtoc_heading_level_1" role="group" ><li class="pac_dtoc_li_heading_level_1" role="treeitem" ><div role="presentation" ><span data-href='#pac_remove_first_heading' data-hl='1'></span><a href='#pac_remove_first_heading' id='pac_remove_first_heading_toc_headding'>FirstHeading</a></div></li><ul class="pac_dtoc_heading_level_2" role="group" ><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#Whyplatformsneedboringmonths' data-hl='2'></span><a href='#Whyplatformsneedboringmonths' id='Whyplatformsneedboringmonths_toc_headding'>Why platforms need “boring months”</a></div></li><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#Redistheshorttermmemorythatkeepseverythingsnappy' data-hl='2'></span><a href='#Redistheshorttermmemorythatkeepseverythingsnappy' id='Redistheshorttermmemorythatkeepseverythingsnappy_toc_headding'>Redis: the short-term memory that keeps everything snappy</a></div></li><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#NativeMongoDBpredictableperformanceclearercontrol' data-hl='2'></span><a href='#NativeMongoDBpredictableperformanceclearercontrol' id='NativeMongoDBpredictableperformanceclearercontrol_toc_headding'>Native MongoDB: predictable performance, clearer control</a></div></li><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#Whatthisunlocksandwhyyoushouldcare' data-hl='2'></span><a href='#Whatthisunlocksandwhyyoushouldcare' id='Whatthisunlocksandwhyyoushouldcare_toc_headding'>What this unlocks (and why you should care)</a></div></li><ul class="pac_dtoc_heading_level_3" role="group" ><li class="pac_dtoc_li_heading_level_3" role="treeitem" ><div role="presentation" ><span data-href='#Fordevelopers' data-hl='3'></span><a href='#Fordevelopers' id='Fordevelopers_toc_headding'>For developers</a></div></li><li class="pac_dtoc_li_heading_level_3" role="treeitem" ><div role="presentation" ><span data-href='#Formerchantsandagencies' data-hl='3'></span><a href='#Formerchantsandagencies' id='Formerchantsandagencies_toc_headding'>For merchants and agencies</a></div></li><li class="pac_dtoc_li_heading_level_3" role="treeitem" ><div role="presentation" ><span data-href='#Forinvestors' data-hl='3'></span><a href='#Forinvestors' id='Forinvestors_toc_headding'>For investors</a></div></li></ul><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#Thehonesttruthaboutperformancework' data-hl='2'></span><a href='#Thehonesttruthaboutperformancework' id='Thehonesttruthaboutperformancework_toc_headding'>The honest truth about performance work</a></div></li><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#Whatsnext' data-hl='2'></span><a href='#Whatsnext' id='Whatsnext_toc_headding'>What’s next</a></div></li><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#Wanttofeeltheseupgradesinyourownintegrations' data-hl='2'></span><a href='#Wanttofeeltheseupgradesinyourownintegrations' id='Wanttofeeltheseupgradesinyourownintegrations_toc_headding'>Want to feel these upgrades in your own integrations?</a></div></li></ul></div>
            </div>
        </div>
        
				</div>
			</div>
			</div>
				
				
				
				
			</div><div class="et_pb_row et_pb_row_14">
				<div class="et_pb_column et_pb_column_4_4 et_pb_column_14  et_pb_css_mix_blend_mode_passthrough et-last-child">
				
				
				
				
				<div class="et_pb_module et_pb_blurb et_pb_blurb_21  et_pb_text_align_left  et_pb_blurb_position_top et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_blurb_content">
					
					<div class="et_pb_blurb_container">
						<h2 class="et_pb_module_header"><span>Why platforms need “boring months”</span></h2>
						<div class="et_pb_blurb_description"><p>Early-stage systems often start with the easiest storage choices and the simplest data paths.</p>
<p>That’s normal. It’s how software is born.</p>
<p>But once usage grows, “easy” turns into:</p>
<ul>
<li>unpredictable latency</li>
<li>costly queries</li>
<li>hard-to-control indexing and performance tuning</li>
<li>caching glued on in random places</li>
<li>mysterious bottlenecks that only appear under load</li>
</ul>
<p>So we did what grown-up platforms eventually do:</p>
<p><strong>We made storage and caching explicit.</strong></p></div>
					</div>
				</div>
			</div>
			</div>
				
				
				
				
			</div><div class="et_pb_row et_pb_row_15">
				<div class="et_pb_column et_pb_column_4_4 et_pb_column_15  et_pb_css_mix_blend_mode_passthrough et-last-child">
				
				
				
				
				<div class="et_pb_module et_pb_blurb et_pb_blurb_22  et_pb_text_align_left  et_pb_blurb_position_top et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_blurb_content">
					
					<div class="et_pb_blurb_container">
						<h2 class="et_pb_module_header"><span>Redis: the short-term memory that keeps everything snappy</span></h2>
						<div class="et_pb_blurb_description"><p>Commerce pipelines often ask the same questions repeatedly:</p>
<ul>
<li>“Give me the current mapping for this channel.”</li>
<li>“What’s the config for this connector?”</li>
<li>“Does this object already exist?”</li>
<li>“What’s the current state for this workflow?”</li>
</ul>
<p>If every question turns into a database roundtrip, the platform becomes slow *and* expensive.</p>
<p>Redis acts like the platform’s <strong>fast short-term memory</strong>:</p>
<ul>
<li>frequently accessed data can be retrieved in milliseconds</li>
<li>downstream services get fewer repeated lookups</li>
<li>throughput increases without brute-force scaling</li>
</ul>
<p>In plain terms: less waiting, fewer database hits, smoother execution.</p></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_23  et_pb_text_align_left  et_pb_blurb_position_top et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_blurb_content">
					
					<div class="et_pb_blurb_container">
						<h2 class="et_pb_module_header"><span>Native MongoDB: predictable performance, clearer control</span></h2>
						<div class="et_pb_blurb_description"><p>At scale, data storage isn’t just “where to put it”.</p>
<p>It’s:</p>
<ul>
<li>how you index it</li>
<li>how you query it</li>
<li>how predictable performance is when the dataset grows</li>
<li>how much operational tuning you can apply</li>
</ul>
<p>Moving toward a native MongoDB setup gives the platform more direct control over:</p>
<ul>
<li>indexes and query optimization</li>
<li>performance characteristics under load</li>
<li>operational consistency across environments</li>
</ul>
<p>It’s the difference between driving a car you can tune… and a car you can only hope behaves.</p></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_24  et_pb_text_align_left  et_pb_blurb_position_top et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_blurb_content">
					
					<div class="et_pb_blurb_container">
						<h2 class="et_pb_module_header"><span>What this unlocks (and why you should care)</span></h2>
						<div class="et_pb_blurb_description"><h3>For developers</h3>
<ul>
<li>fewer “random slowdowns”</li>
<li>more predictable API response times</li>
<li>cleaner separation between “hot” (cached) and “cold” (persisted) data paths</li>
<li>a foundation that supports bigger pipelines without turning into a distributed debugging festival</li>
</ul>
<h3>For merchants and agencies</h3>
<ul>
<li>faster setup workflows in the portal</li>
<li>more stable sync behavior when catalogs and order volume grow</li>
<li>fewer platform hiccups during peak business periods (because commerce always peaks at the worst possible time)</li>
</ul>
<h3>For investors</h3>
<p>Infrastructure work is compounding work:</p>
<ul>
<li>it reduces marginal cost of growth</li>
<li>it raises the ceiling for throughput per customer</li>
<li>it improves reliability, which improves retention</li>
</ul>
<p>It’s not glamorous. It’s how platforms survive success.</p></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_accordion et_pb_accordion_3">
				
				
				
				
				<div class="et_pb_toggle et_pb_module et_pb_accordion_item et_pb_accordion_item_3  et_pb_toggle_open">
				
				
				
				
				<h5 class="et_pb_toggle_title"></h5>
				<div class="et_pb_toggle_content clearfix">We invite you to share your experiences and lessons learned with Qilin.Cloud’s innovative technology platform for composable e-commerce. Your story can inspire others and help the whole community to improve.

&nbsp;
<h4><strong>Share your Qilin.Cloud Success Story</strong>
<span> </span></h4>
<div class="et_pb_button_module_wrapper et_pb_button_0_wrapper  et_pb_module "><a class="et_pb_button et_pb_button_0 et_pb_bg_layout_light" href="https://qilin.cloud/share-your-story/">Your Journey</a></div></div>
			</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_25  et_pb_text_align_left  et_pb_blurb_position_top et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_blurb_content">
					
					<div class="et_pb_blurb_container">
						<h2 class="et_pb_module_header"><span>The honest truth about performance work</span></h2>
						<div class="et_pb_blurb_description"><p>There’s no magic.</p>
<p>Performance comes from making the system’s “invisible” parts intentional:</p>
<ul>
<li>caching with a strategy</li>
<li>storage with predictable behavior</li>
<li>fewer redundant calls</li>
<li>more deterministic execution paths</li>
</ul>
<p>That’s what we’ve been building this month.</p></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_26  et_pb_text_align_left  et_pb_blurb_position_top et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_blurb_content">
					
					<div class="et_pb_blurb_container">
						<h2 class="et_pb_module_header"><span>What’s next</span></h2>
						<div class="et_pb_blurb_description"><p>Now that the foundation is getting faster and sturdier, we can spend more energy on what users interact with every day:</p>
<p><strong>building pipelines and channels more easily, safely, and visibly.</strong></p>
<p>January will focus on the pipeline-building experience &#8211; from creating flows to tracking executions without needing a magnifying glass and a prayer.</p></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_27  et_pb_text_align_left  et_pb_blurb_position_top et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_blurb_content">
					
					<div class="et_pb_blurb_container">
						<h2 class="et_pb_module_header"><span>Want to feel these upgrades in your own integrations?</span></h2>
						<div class="et_pb_blurb_description"><p>If you’ve been running commerce syncs long enough, you know: reliability and speed aren’t “nice-to-haves” &#8211; they’re the difference between operational calm and constant fire drills.</p>
<p>Qilin.Cloud is here for the calm.</p></div>
					</div>
				</div>
			</div>
			</div>
				
				
				
				
			</div>
				
				
			</div>
<p>The post <a rel="nofollow" href="https://qilin.cloud/engine-tune-up-redis-mongodb-performance-foundations/">The Engine Tune-Up: Redis, MongoDB, and the Performance Foundations of Qilin.Cloud</a> appeared first on <a rel="nofollow" href="https://qilin.cloud">Qilin.Cloud</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>How to Orchestrate Best-of-Breed Technologies in Digital Commerce</title>
		<link>https://qilin.cloud/how-to-orchestrate-best-of-breed-technologies-in-digital-commerce/</link>
					<comments>https://qilin.cloud/how-to-orchestrate-best-of-breed-technologies-in-digital-commerce/#comments</comments>
		
		<dc:creator><![CDATA[Marc Costea]]></dc:creator>
		<pubDate>Sun, 14 Jan 2024 22:00:00 +0000</pubDate>
				<category><![CDATA[Uncategorized]]></category>
		<guid isPermaLink="false">https://qilin.cloud/?p=2154</guid>

					<description><![CDATA[<p>The post <a rel="nofollow" href="https://qilin.cloud/how-to-orchestrate-best-of-breed-technologies-in-digital-commerce/">How to Orchestrate Best-of-Breed Technologies in Digital Commerce</a> appeared first on <a rel="nofollow" href="https://qilin.cloud">Qilin.Cloud</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<div class="et_pb_section et_pb_section_2 et_section_regular" >
				
				
				
				
				
				
				<div class="et_pb_row et_pb_row_16">
				<div class="et_pb_column et_pb_column_4_4 et_pb_column_16  et_pb_css_mix_blend_mode_passthrough et-last-child">
				
				
				
				
				<div class="et_pb_module et_pb_text et_pb_text_4  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><p>The days of monolithic software systems in B2B and sophisticated B2C commerce are over. Find out here where the technology journey is heading and what role cloud-native composable commerce platforms such as Qilin.Cloud play in this.</p>
<p>Back in 2014, Gartner pointed out that flexibility plays a decisive role in the future viability of companies. This refers to the flexibility to adapt to new requirements in real time and to develop resilience in the face of uncertainty. This insight gave rise to the idea of composable business, which focuses on modular structures and the orchestration of technologies.</p></div>
			</div><div class="et_pb_module et_pb_text et_pb_text_5  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><blockquote>
<p><strong><em>&#8220;Composable Business is a company that consists of interchangeable building blocks. These building blocks enable companies to change quickly.&#8221;</em></strong></p>
<p><a href="https://www.gartner.de/de/artikel/gartner-keynote-die-zukunft-des-composable-business" target="_blank" rel="noopener">Gartner</a></p>
</blockquote></div>
			</div>
			</div>
				
				
				
				
			</div><div class="et_pb_row et_pb_row_17">
				<div class="et_pb_column et_pb_column_4_4 et_pb_column_17  et_pb_css_mix_blend_mode_passthrough et-last-child">
				
				
				
				
				<div class="et_pb_module et_pb_accordion et_pb_accordion_4">
				
				
				
				
				<div class="et_pb_toggle et_pb_module et_pb_accordion_item et_pb_accordion_item_4  et_pb_toggle_open">
				
				
				
				
				<h2 class="et_pb_toggle_title">tl;dr</h2>
				<div class="et_pb_toggle_content clearfix"><ul>
	<li>Monolithic software systems are reaching their limits in B2B and demanding B2C commerce in terms of adaptability and scalability</li><br>
	<li>The constant need for migration projects with traditional systems keeps valuable resources away from innovation</li><br>
	<li>Unlike monolithic systems, composable commerce platforms are designed for agile change and adaptation</li><br>
	<li>The MACH-OPC principles of microservices-based, API-first, cloud-native SaaS and headless form the technological basis for composable commerce</li><br>
	<li>Composable commerce platforms such as Qilin.Cloud are particularly suitable for complex business processes that standard store solutions cannot map</li>
</ul></div>
			</div>
			</div>
			</div>
				
				
				
				
			</div><div class="et_pb_row et_pb_row_18">
				<div class="et_pb_column et_pb_column_4_4 et_pb_column_18  et_pb_css_mix_blend_mode_passthrough et-last-child">
				
				
				
				
				<div class="et_pb_module et_pb_text et_pb_text_6  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><h2>The Evolution of E-Commerce Systems</h2></div>
			</div><div class="et_pb_module et_pb_text et_pb_text_7  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><p>E-commerce technologies are developing at a rapid pace. While monolithic complete systems dominated digital sales just 20 years ago, we are now seeing a clear trend towards systems that enable greater modularity and flexibility. Rigid, prefabricated solutions are now being replaced by agile structures that allow the best solutions &#8211; <a href="https://qilin.cloud/best-of-breed/">best-of-breed</a> &#8211; to be individually orchestrated for specific requirements.</p>
<p>The reasons for this development are obvious: most of the leading e-commerce solutions that still dominate the market today were developed decades ago. At a time when the demands on the flexibility and adaptability of digital commerce were not as high as they are today. So it&#8217;s no wonder that such systems, even if they claim to be composable, have their limits.</p>
<p>Monolithic systems are generally not designed for change. As a result, innovations can only be implemented slowly and with considerable effort. Peak loads during operation cannot be flexibly absorbed because the system lacks <a href="https://qilin.cloud/processing-speed">scalability</a>. In order to guarantee an optimal shopping experience at all times, more server capacity is required, which leads to costly overcapacity during normal operation.</p>
<p>Further disadvantages of monolithic systems result from the dependency on the provider, who determines the rhythm and scope of software updates. On the one hand, updates are often of no business benefit, but still cost a lot of money. On the other hand, companies often wait a long time for important innovations that are urgently needed for competitive e-commerce &#8211; both negative consequences of vendor lock-in.</p>
<p>Last but not least, monolithic e-commerce systems can be very complex and costly to operate and develop. The more complex and individual the business, the higher the total cost of ownership (TCO) for technologies that are not designed for change and adaptation to new requirements. Incidentally, this also applies to monolithic systems in which the front end and back end are decoupled according to the headless principle.</p></div>
			</div><div class="et_pb_module et_pb_text et_pb_text_8  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><blockquote>
<p><em><strong>&#8220;With monolithic e-commerce systems that are not designed for change and adaptation, the migration of new functions and processes takes up 20-50% of development resources.&#8221;</strong></em></p>
</blockquote></div>
			</div><div class="et_pb_module et_pb_image et_pb_image_0">
				
				
				
				
				<span class="et_pb_image_wrap "><img data-dominant-color="253f54" data-has-transparency="false" style="--dominant-color: #253f54;" fetchpriority="high" decoding="async" width="1280" height="720" src="https://qilin.cloud/wp-content/uploads/2023/12/gartnercomposablecommerce.jpg" alt="gartnercomposablecommerce" title="gartnercomposablecommerce" srcset="https://qilin.cloud/wp-content/uploads/2023/12/gartnercomposablecommerce.jpg 1280w, https://qilin.cloud/wp-content/uploads/2023/12/gartnercomposablecommerce-980x551.webp 980w, https://qilin.cloud/wp-content/uploads/2023/12/gartnercomposablecommerce-480x270.webp 480w" sizes="(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 1280px, 100vw" class="wp-image-2158 not-transparent"></span>
			</div>
			</div>
				
				
				
				
			</div><div class="et_pb_row et_pb_row_19">
				<div class="et_pb_column et_pb_column_4_4 et_pb_column_19  et_pb_css_mix_blend_mode_passthrough et-last-child">
				
				
				
				
				<div class="et_pb_module et_pb_text et_pb_text_9  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><h2>Advantages of a MACH-OPC-based Composable Commerce Architecture</h2></div>
			</div><div class="et_pb_module et_pb_text et_pb_text_10  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><p>Gartner defines composable commerce as an architectural approach to digital commerce in which applications are implemented with the help of packaged business capabilities (PBCs). PBCs are software components that represent a clearly defined business capability. Here, too, it is worth taking a closer look, because although PBCs are always modular, they are not necessarily built in a truly modern way, i.e. on the basis of microservices as part of a service-oriented architecture (SOA).</p></div>
			</div><div class="et_pb_button_module_wrapper et_pb_button_0_wrapper  et_pb_module ">
				<a class="et_pb_button et_pb_button_0 et_pb_bg_layout_light" href="https://qilin.cloud/composable-commerce">Read more about Composable Commerce</a>
			</div><div class="et_pb_module et_pb_text et_pb_text_11  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><p>The technological requirements for composable commerce are reflected in the so-called MACH principles:</p>
<ul>
<li style="list-style-type: none;">
<ul>
<li style="list-style-type: none;">
<ul>
<li><em> microservices-based, </em></li>
<li><em>API-first, </em></li>
<li><em>cloud-native SaaS and </em></li>
<li><em>headless.</em></li>
</ul>
</li>
</ul>
</li>
</ul>
<p>Qilin.Cloud raised this approach to the next level with integrating</p>
<ul>
<li style="list-style-type: none;">
<ul>
<li style="list-style-type: none;">
<ul>
<li><em>open,</em></li>
<li><em>process-centric and</em></li>
<li><em>composable</em></li>
</ul>
</li>
</ul>
</li>
</ul>
<p>to its statutes.</p>
<p>Genuine composable commerce platforms support all four principles, because only in combination do they enable companies to flexibly orchestrate best-of-breed solutions and publish mission-critical functions in real time. Qilin.Cloud goes even further and integrated an user- &amp; partner open approach giving the maximum flexibility and security and minimum lock-in effects. Furthermore it&#8217;s process centricity reflects the behave of the business where application are created for on the plattform.</p></div>
			</div><div class="et_pb_button_module_wrapper et_pb_button_1_wrapper  et_pb_module ">
				<a class="et_pb_button et_pb_button_1 et_pb_bg_layout_light" href="https://qilin.cloud/machopc/">Read more about MACH-OPC</a>
			</div><div class="et_pb_module et_pb_text et_pb_text_12  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><blockquote>
<p><strong>In summary, it fair enough to be said that composable commerce platforms based on a MACH-OPC architecture are designed for agile change and adaptation, unlike monolithic systems. This means that innovations can be implemented more quickly and easily. The modular architecture reduces the complexity of the individual system components and therefore also the risk in development, as test routines are less complex and individual components can be easily replaced or added to.</strong></p>
</blockquote></div>
			</div><div class="et_pb_module et_pb_accordion et_pb_accordion_5">
				
				
				
				
				<div class="et_pb_toggle et_pb_module et_pb_accordion_item et_pb_accordion_item_5  et_pb_toggle_open">
				
				
				
				
				<h5 class="et_pb_toggle_title"></h5>
				<div class="et_pb_toggle_content clearfix"><p><em>Join the Crowd, Start disrupting e-Commerce, Become a Qilin, Do the Extraordinary</em> – there are a lot of terms, but only one decission:</p>
<p>&nbsp;</p>
<h4><strong>Start your career at Qilin.Cloud</strong><br /><span> </span></h4>
<div class="et_pb_button_module_wrapper et_pb_button_0_wrapper  et_pb_module "><a class="et_pb_button et_pb_button_0 et_pb_bg_layout_light" href="https://qilin.cloud/career/#vacancies">Our vacancies</a></div></div>
			</div>
			</div>
			</div>
				
				
				
				
			</div><div class="et_pb_row et_pb_row_20">
				<div class="et_pb_column et_pb_column_4_4 et_pb_column_20  et_pb_css_mix_blend_mode_passthrough et-last-child">
				
				
				
				
				<div class="et_pb_module et_pb_text et_pb_text_13  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><h2>Example: Managing the buyer journey in B2B and sophisticated B2C with composable commerce</h2></div>
			</div><div class="et_pb_module et_pb_text et_pb_text_14  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><p>Composable commerce platforms such as Qilin.Cloud are particularly suitable for complex business processes that standard store solutions cannot map or can only map to a limited extent. Such complex processes can be found in B2B and sophisticated B2C in all phases of the buyer journey &#8211; from login, search and catalog to shopping cart and checkout. The following graphic shows examples of typical functional requirements.</p></div>
			</div><div class="et_pb_module et_pb_image et_pb_image_1">
				
				
				
				
				<span class="et_pb_image_wrap "><img data-dominant-color="562f53" data-has-transparency="true" style="--dominant-color: #562f53;" decoding="async" width="915" height="881" src="https://qilin.cloud/wp-content/uploads/2023/08/mach1-1.png" alt="mach1 1" title="mach1" srcset="https://qilin.cloud/wp-content/uploads/2023/08/mach1-1.png 915w, https://qilin.cloud/wp-content/uploads/2023/08/mach1-1-480x462.png 480w" sizes="(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 915px, 100vw" class="wp-image-1508 has-transparency"></span>
			</div><div class="et_pb_module et_pb_text et_pb_text_15  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><p>With a composable commerce architecture, companies are able to add success-critical functions for each phase of the buyer journey in real time or replace outdated ones when requirements change or new opportunities arise through technical innovation. Both best-of-breed components that are available on the market and services developed in-house can be used and combined.</p></div>
			</div><div class="et_pb_module et_pb_text et_pb_text_16  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><blockquote>
<p><em><strong>&#8220;80-120 channels in the company require a commerce architecture that enables digital capabilities, data and domains to be orchestrated flexibly and in real time.&#8221;</strong></em></p>
</blockquote>
<p><strong>Axel Helbig,</strong><br />Chief Executive Officer<br />foryouandyourcustomers</p></div>
			</div><div class="et_pb_module et_pb_text et_pb_text_17  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><p>When switching from a monolithic legacy system to a composable commerce platform, it is essential not only to rethink technology, but also to transform the company as a whole &#8211; organization, processes, data, assets and even culture &#8211; in the direction of a composable business. Technology can be an important driver and compass for this transformation process.</p></div>
			</div>
			</div>
				
				
				
				
			</div>
				
				
			</div>
<p>The post <a rel="nofollow" href="https://qilin.cloud/how-to-orchestrate-best-of-breed-technologies-in-digital-commerce/">How to Orchestrate Best-of-Breed Technologies in Digital Commerce</a> appeared first on <a rel="nofollow" href="https://qilin.cloud">Qilin.Cloud</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://qilin.cloud/how-to-orchestrate-best-of-breed-technologies-in-digital-commerce/feed/</wfw:commentRss>
			<slash:comments>6</slash:comments>
		
		
			</item>
		<item>
		<title>Streamline event-driven microservices with Kafka and Python</title>
		<link>https://qilin.cloud/streamline-event-driven-microservices-with-kafka-and-python/</link>
					<comments>https://qilin.cloud/streamline-event-driven-microservices-with-kafka-and-python/#respond</comments>
		
		<dc:creator><![CDATA[Marc Costea]]></dc:creator>
		<pubDate>Mon, 14 Aug 2023 13:27:34 +0000</pubDate>
				<category><![CDATA[Uncategorized]]></category>
		<guid isPermaLink="false">https://qilin.cloud/?p=717</guid>

					<description><![CDATA[<p>With the rise of big data, cloud, and streaming platforms, monolithic apps just won’t do. Here’s a blueprint for an adaptable and scalable event-driven microservices project using Kafka and Python.</p>
<p>The post <a rel="nofollow" href="https://qilin.cloud/streamline-event-driven-microservices-with-kafka-and-python/">Streamline event-driven microservices with Kafka and Python</a> appeared first on <a rel="nofollow" href="https://qilin.cloud">Qilin.Cloud</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><div class="et_pb_section et_pb_section_3 et_section_regular" >
				
				
				
				
				
				
				<div class="et_pb_row et_pb_row_21">
				<div class="et_pb_column et_pb_column_4_4 et_pb_column_21  et_pb_css_mix_blend_mode_passthrough et-last-child">
				
				
				
				
				<div class="et_pb_module et_pb_text et_pb_text_18  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><p>For many critical application functions, including streaming and e-commerce, monolithic architecture is no longer sufficient. With current demands for real-time event data and cloud service usage, many modern applications, such as Netflix and Lyft, have shifted to an event-driven<span> </span>microservices<span> </span>approach. Separated microservices can operate independently of one another and enhance a code base’s adaptability and scalability.</p>
<p>But what is an event-driven microservices architecture, and why should you use it? We’ll examine the foundational aspects and create a complete blueprint for an event-driven microservices project using<span> </span>Python<span> </span>and<span> </span>Apache Kafka.</p></div>
			</div><div class="et_pb_module et_pb_text et_pb_text_19  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><h2 id="using-event-driven-microservices">Using Event-driven Microservices</h2>
<p>Event-driven microservices combine two modern architecture patterns: microservices architectures and event-driven architectures. Though microservices can pair with request-driven REST architectures, event-driven architectures are becoming increasingly relevant with the rise of big data and cloud platform environments.</p></div>
			</div><div class="et_pb_module et_pb_text et_pb_text_20  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><h3 id="what-is-a-microservices-architecture">What Is a Microservices Architecture?</h3>
<p>A microservices architecture is a software development technique that organizes an application’s processes as loosely coupled services. It is a type of<span> </span>service-oriented architecture (SOA).</p>
<p>In a traditional monolithic structure, all application processes are inherently interconnected; if one part fails, the system goes down. Microservices architectures instead group application processes into separate services interacting with lightweight protocols, providing improved modularity and better app maintainability and resiliency.</p></div>
			</div><div class="et_pb_module et_pb_image et_pb_image_2">
				
				
				
				
				<a href="https://qilin.cloud/wp-content/uploads/2023/08/blog4-1.jpg" class="et_pb_lightbox_image" title=""><span class="et_pb_image_wrap "><img loading="lazy" decoding="async" width="1357" height="975" src="https://qilin.cloud/wp-content/uploads/2023/08/blog4-1.jpg" alt="blog4 1" title="blog4-1" srcset="https://qilin.cloud/wp-content/uploads/2023/08/blog4-1.jpg 1357w, https://qilin.cloud/wp-content/uploads/2023/08/blog4-1-1280x920.jpg 1280w, https://qilin.cloud/wp-content/uploads/2023/08/blog4-1-980x704.jpg 980w, https://qilin.cloud/wp-content/uploads/2023/08/blog4-1-480x345.jpg 480w" sizes="(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) and (max-width: 1280px) 1280px, (min-width: 1281px) 1357px, 100vw" class="wp-image-722"></span></a>
			</div><div class="et_pb_module et_pb_text et_pb_text_21  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><p><span>Though monolithic applications may be simpler to develop, debug, </span>test<span>, and deploy, most enterprise-level applications turn to microservices as their standard, which allows developers to own components independently. Successful microservices should be kept as simple as possible and communicate using messages (events) that are produced and sent to an event stream or consumed from an event stream. JSON, Apache Avro, and Google Protocol Buffers are common choices for data serialization.</span></p></div>
			</div><div class="et_pb_module et_pb_text et_pb_text_22  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><h3 id="what-is-an-event-driven-architecture">What Is an Event-driven Architecture?</h3>
<p>An event-driven architecture is a design pattern that structures software so that events drive the behavior of an application. Events are meaningful data generated by<span> </span><em>actors<span> </span></em>(i.e., human users, external applications, or other services).</p>
<p>Our example project features this architecture; at its core is an event-streaming platform that manages communication in two ways:</p>
<ul>
<li><strong>Receiving messages</strong><span> </span>from actors that write them (usually called publishers or producers)</li>
<li><strong>Sending messages</strong><span> </span>to other actors that read them (usually called subscribers or consumers)</li>
</ul>
<p>In more technical terms, our event-streaming platform is software that acts as the communication layer between services and allows them to exchange messages. It can implement a variety of messaging patterns, such as<span> </span>publish/subscribe<span> </span>or<span> </span><a href="https://www.ibm.com/docs/en/wip-mg/2.0.0?topic=concepts-point-point-messaging" target="_blank" rel="noopener">point-to-point messaging</a>, as well as<span> </span><a href="https://aws.amazon.com/message-queue/" target="_blank" rel="noopener">message queues</a>.</p></div>
			</div><div class="et_pb_module et_pb_image et_pb_image_3">
				
				
				
				
				<span class="et_pb_image_wrap "><img loading="lazy" decoding="async" width="1533" height="1066" src="https://qilin.cloud/wp-content/uploads/2023/08/blog4-2.gif" alt="blog4 2" title="blog4-2" class="wp-image-723"></span>
			</div><div class="et_pb_module et_pb_text et_pb_text_23  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><p>Using an event-driven architecture with an event-streaming platform and microservices offers a wealth of benefits:</p>
<ul>
<li><strong>Asynchronous communications:</strong><span> </span>The ability to independently multitask allows services to react to events whenever they are ready instead of waiting on a previous task to finish before starting the next one. Asynchronous communications facilitate real-time data processing and make applications more reactive and maintainable.</li>
<li><strong>Complete decoupling and flexibility:</strong><span> </span>The separation of producer and consumer components means that services only need to interact with the event-streaming platform and the data format they can produce or consume. Services can follow the<span> </span>single responsibility principle<span> </span>and scale independently. They can even be implemented by separate development teams using unique technology stacks.</li>
<li><strong>Reliability and scalability:</strong><span> </span>The asynchronous, decoupled nature of event-driven architectures further amplifies app reliability and scalability (which are already advantages of microservices architecture design).</li>
</ul>
<p>With event-driven architectures, it’s easy to create services that react to any system event. You can also create semi-automatic pipelines that include some manual actions. (For example, a pipeline for automated user payouts might include a manual security check triggered by unusually large payout values before transferring funds.)</p></div>
			</div><div class="et_pb_module et_pb_text et_pb_text_24  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><h2 id="choosing-the-project-tech-stack">Choosing the Project Tech Stack</h2>
<p>We will create our project using Python and Apache Kafka paired with Confluent Cloud.<span> </span>Python is a robust, reliable standard for many types of software projects; it boasts a large community and plentiful libraries. It is a good choice for creating microservices because its frameworks are suited to REST and event-driven applications (e.g., Flask and<span> </span>Django). Microservices written in Python are also commonly used with Apache Kafka.</p>
<p>Apache Kafka is a well-known event-streaming platform that uses a publish/subscribe messaging pattern. It is a common choice for event-driven architectures due to its extensive ecosystem, scalability (the result of its fault-tolerance abilities), storage system, and stream processing abilities.</p>
<p>Lastly, we will use Confluent as our cloud platform to efficiently manage Kafka and provide out-of-the-box infrastructure. AWS MSK is another excellent option if you’re using AWS infrastructure, but Confluent is easier to set up as Kafka is the core part of its system and it offers a free tier.</p></div>
			</div><div class="et_pb_module et_pb_text et_pb_text_25  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><h2 id="implementing-the-project-blueprint">Implementing the Project Blueprint</h2>
<p>We’ll set up our Kafka microservices example in Confluent Cloud, create a simple message producer, then organize and improve it to optimize scalability. By the end of this tutorial, we will have a functioning message producer that successfully sends data to our cloud cluster.</p></div>
			</div><div class="et_pb_module et_pb_text et_pb_text_26  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><h3 id="kafka-setup">Kafka Setup</h3>
<p>We’ll first create a Kafka cluster. Kafka clusters host Kafka servers that facilitate communication. Producers and consumers interface with the servers using Kafka topics (categories storing records).</p>
<ol>
<li>Sign up for<span> </span><a href="https://confluent.cloud/" target="_blank" rel="noopener">Confluent Cloud</a>. Once you create an account, the welcome page appears with options for creating a new Kafka cluster. Select the<span> </span><strong>Basic</strong><span> </span>configuration.</li>
<li>Choose a cloud provider and region. You should optimize your choices for the best cloud ping results from your location. One option is to choose<span> </span><strong>AWS</strong><span> </span>and perform a<span> </span><a href="https://www.cloudping.cloud/aws" target="_blank" rel="noopener">cloud ping test</a><span> </span>(click<span> </span><strong>HTTP Ping</strong>) to identify the best region. (For the scope of our tutorial, we will leave the “Single zone” option selected in the “Availability” field.)</li>
<li>The next screen asks for a payment setup, which we can skip since we are on a free tier. After that, we will enter our cluster name (e.g., “MyFirstKafkaCluster”), confirm our settings, and select<span> </span><strong>Launch cluster</strong>.</li>
</ol></div>
			</div><div class="et_pb_module et_pb_image et_pb_image_4">
				
				
				
				
				<a href="https://qilin.cloud/wp-content/uploads/2023/08/blog4-3.jpg" class="et_pb_lightbox_image" title=""><span class="et_pb_image_wrap "><img loading="lazy" decoding="async" width="836" height="774" src="https://qilin.cloud/wp-content/uploads/2023/08/blog4-3.jpg" alt="blog4 3" title="blog4-3" srcset="https://qilin.cloud/wp-content/uploads/2023/08/blog4-3.jpg 836w, https://qilin.cloud/wp-content/uploads/2023/08/blog4-3-480x444.jpg 480w" sizes="(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 836px, 100vw" class="wp-image-724"></span></a>
			</div><div class="et_pb_module et_pb_text et_pb_text_27  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><p>With a working cluster, we are ready to create our first topic. In the left-hand menu bar, navigate to<span> </span><strong>Topics</strong><span> </span>and click<span> </span><strong>Create topic</strong>. Add a topic name (e.g., “MyFirstKafkaTopic”) and continue with the default configurations (including setting six partitions).</p>
<p>Before creating our first message, we must set up our client. We can easily<span> </span><strong>Configure a client</strong><span> </span>from our newly created topic overview (alternatively, in the left-hand menu bar, navigate to<span> </span><strong>Clients</strong>). We’ll use<span> </span><strong>Python</strong><span> </span>as our language and then click<span> </span><strong>Create Kafka cluster API key</strong>.</p></div>
			</div><div class="et_pb_module et_pb_image et_pb_image_5">
				
				
				
				
				<a href="https://qilin.cloud/wp-content/uploads/2023/08/blog4-4.jpg" class="et_pb_lightbox_image" title=""><span class="et_pb_image_wrap "><img loading="lazy" decoding="async" width="1085" height="691" src="https://qilin.cloud/wp-content/uploads/2023/08/blog4-4.jpg" alt="blog4 4" title="blog4-4" srcset="https://qilin.cloud/wp-content/uploads/2023/08/blog4-4.jpg 1085w, https://qilin.cloud/wp-content/uploads/2023/08/blog4-4-980x624.jpg 980w, https://qilin.cloud/wp-content/uploads/2023/08/blog4-4-480x306.jpg 480w" sizes="(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 1085px, 100vw" class="wp-image-725"></span></a>
			</div><div class="et_pb_module et_pb_text et_pb_text_28  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><p><span>At this point, our event-streaming platform is finally ready to receive messages from our producer.</span></p></div>
			</div><div class="et_pb_module et_pb_text et_pb_text_29  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><h3 id="simple-message-producer">Simple Message Producer</h3>
<p>Our producer generates events and sends them to Kafka. Let’s write some code to create a simple message producer. I recommend<span> </span><a href="https://packaging.python.org/en/latest/guides/installing-using-pip-and-virtual-environments/" target="_blank" rel="noopener">setting up a virtual environment</a><span> </span>for our project since we will be installing multiple packages in our environment.</p>
<p>First, we will add our environment variables from the API configuration from Confluent Cloud. To do this in our virtual environment, we’ll add<span> </span><code>export SETTING=value</code><span> </span>for each setting below to the end of our<span> </span><code>activate</code><span> </span>file (alternatively, you can add<span> </span><code>SETTING=value</code><span> </span>to your .env file):</p></div>
			</div><div class="et_pb_module et_pb_text et_pb_text_30  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><p>export KAFKA_BOOTSTRAP_SERVERS=&lt;bootstrap.servers&gt;<br />export KAFKA_SECURITY_PROTOCOL=&lt;security.protocol&gt;<br />export KAFKA_SASL_MECHANISMS=&lt;sasl.mechanisms&gt;<br />export KAFKA_SASL_USERNAME=&lt;sasl.username&gt;<br />export KAFKA_SASL_PASSWORD=&lt;sasl.password&gt;</p></div>
			</div><div class="et_pb_module et_pb_text et_pb_text_31  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><p>Make sure to replace each entry with your Confluent Cloud values (for example,<span> </span><code>&lt;sasl.mechanisms&gt;</code><span> </span>should be<span> </span><code>PLAIN</code>), with your API key and secret as the username and password. Run<span> </span><code>source env/bin/activate</code>, then<span> </span><code>printenv</code>. Our new settings should appear, confirming that our variables have been correctly updated.</p>
<p>We will be using two Python packages:</p>
<ul>
<li><a href="https://pypi.org/project/python-dotenv/" target="_blank" rel="noopener"><code>python-dotenv</code><span> </span>package</a>: Loads and sets environment variables.</li>
<li><a href="https://docs.confluent.io/kafka-clients/python/current/overview.html#ak-python" target="_blank" rel="noopener"><code>confluent-kafka</code><span> </span>package</a>: Provides producer and consumer functionality; our Python client for Kafka.</li>
</ul>
<p>We’ll run the command<span> </span><code>pip install confluent-kafka python-dotenv</code><span> </span>to install these. There are many other<span> </span><a href="https://towardsdatascience.com/3-libraries-you-should-know-to-master-apache-kafka-in-python-c95fdf8700f2?gi=bdff5909db6b" target="_blank" rel="noopener">packages for Kafka</a><span> </span>in Python that may be useful as you expand your project.</p>
<p>Finally, we’ll create our basic producer using our Kafka settings. Add a<span> </span><code>simple_producer.py</code><span> </span>file:</p></div>
			</div><div class="et_pb_module et_pb_text et_pb_text_32  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"># simple_producer.py<br />
import os</p>
<p>from confluent_kafka import KafkaException, Producer<br />
from dotenv import load_dotenv</p>
<p>def main():<br />
&emsp;settings = {<br />
&emsp;&emsp;&#8217;bootstrap.servers&#8217;: os.getenv(&#8216;KAFKA_BOOTSTRAP_SERVERS&#8217;),<br />
&emsp;&emsp;&#8217;security.protocol&#8217;: os.getenv(&#8216;KAFKA_SECURITY_PROTOCOL&#8217;),<br />
&emsp;&emsp;&#8217;sasl.mechanisms&#8217;: os.getenv(&#8216;KAFKA_SASL_MECHANISMS&#8217;),<br />
&emsp;&emsp;&#8217;sasl.username&#8217;: os.getenv(&#8216;KAFKA_SASL_USERNAME&#8217;),<br />
&emsp;&emsp;&#8217;sasl.password&#8217;: os.getenv(&#8216;KAFKA_SASL_PASSWORD&#8217;),<br />
&emsp;}</p>
<p>&emsp;producer = Producer(settings)<br />
&emsp;producer.produce(<br />
&emsp;&emsp;topic=&#8217;MyFirstKafkaTopic&#8217;,<br />
&emsp;&emsp;&emsp;&emsp;&emsp;key=None,<br />
&emsp;&emsp;&emsp;&emsp;&emsp;value=&#8217;MyFirstValue-111&#8242;,<br />
&emsp;)<br />
&emsp;producer.flush()  # Wait for the receive confirmation</p>
<p>if __name__ == &#8216;__main__&#8217;:<br />
&emsp;load_dotenv()<br />
&emsp;main()</div>
			</div><div class="et_pb_module et_pb_text et_pb_text_33  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><p><span>With this straightforward code we create our producer and send it a simple test message. To test the result, run </span><code>python3 simple_producer.py</code><span>:</span></p></div>
			</div><div class="et_pb_module et_pb_image et_pb_image_6">
				
				
				
				
				<a href="https://qilin.cloud/wp-content/uploads/2023/08/blog4-5.jpg" class="et_pb_lightbox_image" title=""><span class="et_pb_image_wrap "><img loading="lazy" decoding="async" width="1318" height="666" src="https://qilin.cloud/wp-content/uploads/2023/08/blog4-5.jpg" alt="blog4 5" title="blog4-5" srcset="https://qilin.cloud/wp-content/uploads/2023/08/blog4-5.jpg 1318w, https://qilin.cloud/wp-content/uploads/2023/08/blog4-5-1280x647.jpg 1280w, https://qilin.cloud/wp-content/uploads/2023/08/blog4-5-980x495.jpg 980w, https://qilin.cloud/wp-content/uploads/2023/08/blog4-5-480x243.jpg 480w" sizes="(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) and (max-width: 1280px) 1280px, (min-width: 1281px) 1318px, 100vw" class="wp-image-726"></span></a>
			</div><div class="et_pb_module et_pb_text et_pb_text_34  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><p><span>Checking our Kafka cluster’s </span><strong>Cluster Overview &gt; Dashboard</strong><span>, we will see a new data point on our Production graph for the message sent.</span></p></div>
			</div><div class="et_pb_module et_pb_text et_pb_text_35  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><h3 id="custom-message-producer">Custom Message Producer</h3>
<p>Our producer is up and running. Let’s reorganize our code to make our project more modular and<span> </span><a href="https://www.geeksforgeeks.org/python-oops-concepts/" target="_blank" rel="noopener">OOP-friendly</a>. This will make it easier to add services and scale our project in the future. We’ll split our code into four files:</p>
<ul>
<li><code>kafka_settings.py</code>: Holds our Kafka configurations.</li>
<li><code>kafka_producer.py</code>: Contains a custom<span> </span><code>produce()</code><span> </span>method and error handling.</li>
<li><code>kafka_producer_message.py</code>: Handles different input data types.</li>
<li><code>advanced_producer.py</code>: Runs our final app using our custom classes.</li>
</ul>
<p>First, our<span> </span><code>KafkaSettings</code><span> </span>class will encapsulate our Apache Kafka settings, so we can easily access these from our other files without repeating code:</p></div>
			</div><div class="et_pb_module et_pb_text et_pb_text_36  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"># kafka_settings.py<br />
import os</p>
<p>class KafkaSettings:<br />
&emsp;def __init__(self):<br />
&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;self.conf = {<br />
&emsp;&emsp;&emsp;&#8217;bootstrap.servers&#8217;: os.getenv(&#8216;KAFKA_BOOTSTRAP_SERVERS&#8217;),<br />
&emsp;&emsp;&emsp;&#8217;security.protocol&#8217;: os.getenv(&#8216;KAFKA_SECURITY_PROTOCOL&#8217;),<br />
&emsp;&emsp;&emsp;&#8217;sasl.mechanisms&#8217;: os.getenv(&#8216;KAFKA_SASL_MECHANISMS&#8217;),<br />
&emsp;&emsp;&emsp;&#8217;sasl.username&#8217;: os.getenv(&#8216;KAFKA_SASL_USERNAME&#8217;),<br />
&emsp;&emsp;&emsp;&#8217;sasl.password&#8217;: os.getenv(&#8216;KAFKA_SASL_PASSWORD&#8217;),<br />
&emsp;&emsp;}</div>
			</div><div class="et_pb_module et_pb_text et_pb_text_37  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><p><span>Next, our </span><code>KafkaProducer</code><span> allows us to customize our </span><code>produce()</code><span> method with support for various errors (e.g., an error when the message size is too large), and also automatically </span><a href="https://kafka.apache.org/11/javadoc/org/apache/kafka/clients/producer/KafkaProducer.html#flush--" target="_blank" rel="noopener">flushes messages</a><span> once produced:</span></p></div>
			</div><div class="et_pb_module et_pb_text et_pb_text_38  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"># kafka_producer.py<br />
from confluent_kafka import KafkaError, KafkaException, Producer</p>
<p>from kafka_producer_message import ProducerMessage<br />
from kafka_settings import KafkaSettings</p>
<p>class KafkaProducer:<br />
&emsp;def __init__(self, settings: KafkaSettings):<br />
&emsp;&emsp;self._producer = Producer(settings.conf)</p>
<p>&emsp;def produce(self, message: ProducerMessage):<br />
&emsp;&emsp;try:<br />
&emsp;&emsp;&emsp;self._producer.produce(message.topic, key=message.key, value=message.value)<br />
&emsp;&emsp;&emsp;self._producer.flush()<br />
&emsp;&emsp;except KafkaException as exc:<br />
&emsp;&emsp;if exc.args[0].code() == KafkaError.MSG_SIZE_TOO_LARGE:<br />
&emsp;&emsp;&emsp;pass  # Handle the error here<br />
&emsp;&emsp;else:<br />
&emsp;&emsp;&emsp;raise exc</div>
			</div><div class="et_pb_module et_pb_text et_pb_text_39  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><p>In our example’s try-except block, we skip over the message if it is too large for the Kafka cluster to consume. However, you should update your code in production to handle this error appropriately. Refer to the<span> </span><code>confluent-kafka</code><span> </span><a href="https://docs.confluent.io/5.5.0/clients/confluent-kafka-python/index.html?highlight=kafkaerror#confluent_kafka.KafkaError" target="_blank" rel="noopener">documentation</a><span> </span>for a complete list of error codes.</p>
<p>Now, our<span> </span><code>ProducerMessage</code><span> </span>class handles different types of input data and correctly serializes them. We’ll add functionality for dictionaries, Unicode strings, and byte strings:</p></div>
			</div><div class="et_pb_module et_pb_text et_pb_text_40  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"># kafka_producer_message.py<br />
import json</p>
<p>class ProducerMessage:<br />
&emsp;def __init__(self, topic: str, value, key=None) -> None:<br />
&emsp;&emsp;self.topic = f'{topic}&#8217;<br />
&emsp;&emsp;self.key = key<br />
&emsp;&emsp;self.value = self.convert_value_to_bytes(value)</p>
<p>&emsp;&emsp;@classmethod<br />
&emsp;&emsp;def convert_value_to_bytes(cls, value):<br />
&emsp;&emsp;&emsp;if isinstance(value, dict):<br />
&emsp;&emsp;&emsp;&emsp;return cls.from_json(value)</p>
<p>&emsp;&emsp;&emsp;if isinstance(value, str):<br />
&emsp;&emsp;&emsp;&emsp;return cls.from_string(value)</p>
<p>&emsp;&emsp;&emsp;if isinstance(value, bytes):<br />
&emsp;&emsp;&emsp;&emsp;return cls.from_bytes(value)</p>
<p>&emsp;&emsp;&emsp;raise ValueError(f&#8217;Wrong message value type: {type(value)}&#8217;)</p>
<p>&emsp;&emsp;@classmethod<br />
&emsp;&emsp;def from_json(cls, value):<br />
&emsp;&emsp;&emsp;return json.dumps(value, indent=None, sort_keys=True, default=str, ensure_ascii=False)</p>
<p>&emsp;&emsp;@classmethodd<br />
&emsp;&emsp;def from_string(cls, value):<br />
&emsp;&emsp;&emsp;return value.encode(&#8216;utf-8&#8217;)</p>
<p>&emsp;&emsp;@classmethod<br />
&emsp;&emsp;def from_bytes(cls, value):<br />
&emsp;&emsp;&emsp;return value</div>
			</div><div class="et_pb_module et_pb_text et_pb_text_41  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><p><span>Finally, we can build our app using our newly created classes in </span><code>advanced_producer.py</code><span>:</span></p></div>
			</div><div class="et_pb_module et_pb_text et_pb_text_42  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"># advanced_producer.py<br />
from dotenv import load_dotenv</p>
<p>from kafka_producer import KafkaProducer<br />
from kafka_producer_message import ProducerMessage<br />
from kafka_settings import KafkaSettings</p>
<p>def main():<br />
&emsp;settings = KafkaSettings()<br />
&emsp;producer = KafkaProducer(settings)<br />
&emsp;message = ProducerMessage(<br />
&emsp;&emsp;topic=&#8217;MyFirstKafkaTopic&#8217;,<br />
&emsp;&emsp;value={&#8220;value&#8221;: &#8220;MyFirstKafkaValue&#8221;},<br />
&emsp;&emsp;key=None,<br />
&emsp;)<br />
&emsp;producer.produce(message)</p>
<p>if __name__ == &#8216;__main__&#8217;:<br />
&emsp;load_dotenv()<br />
&emsp;main()</div>
			</div><div class="et_pb_module et_pb_text et_pb_text_43  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><p><span>We now have a neat abstraction above the </span><code>confluent-kafka</code><span> library. </span><a href="https://github.com/dmitryshurov/toptal_microservices_tutorial" target="_blank" rel="noopener">Our custom producer</a><span> possesses the same functionality as our simple producer with added scalability and flexibility, ready to adapt to various needs. We could even change the underlying library entirely if we wanted to, which sets our project up for success and long-term maintainability.</span></p></div>
			</div><div class="et_pb_module et_pb_image et_pb_image_7">
				
				
				
				
				<a href="https://qilin.cloud/wp-content/uploads/2023/08/blog4-6.jpg" class="et_pb_lightbox_image" title=""><span class="et_pb_image_wrap "><img loading="lazy" decoding="async" width="1326" height="674" src="https://qilin.cloud/wp-content/uploads/2023/08/blog4-6.jpg" alt="blog4 6" title="blog4-6" srcset="https://qilin.cloud/wp-content/uploads/2023/08/blog4-6.jpg 1326w, https://qilin.cloud/wp-content/uploads/2023/08/blog4-6-1280x651.jpg 1280w, https://qilin.cloud/wp-content/uploads/2023/08/blog4-6-980x498.jpg 980w, https://qilin.cloud/wp-content/uploads/2023/08/blog4-6-480x244.jpg 480w" sizes="(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) and (max-width: 1280px) 1280px, (min-width: 1281px) 1326px, 100vw" class="wp-image-734"></span></a>
			</div><div class="et_pb_module et_pb_text et_pb_text_44  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><p><span>After running </span><code>python3 advanced_producer.py</code><span>, we see yet again that data has been sent to our cluster in the </span><strong>Cluster Overview &gt; Dashboard</strong><span> panel of Confluent Cloud. Having sent one message with the simple producer, and a second with our custom producer, we now see two spikes in production throughput and an increase in overall storage used.</span></p></div>
			</div><div class="et_pb_module et_pb_text et_pb_text_45  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><h2 id="looking-ahead-from-producers-to-consumers">Looking Ahead: From Producers to Consumers</h2>
<p>An event-driven microservices architecture will enhance your project and improve its scalability, flexibility, reliability, and asynchronous communications. This tutorial has given you a glimpse of these benefits in action. With our enterprise-scale producer up and running, sending messages successfully to our Kafka broker, the next steps would be to create a consumer to read these messages from other services and add Docker to our application.</p></div>
			</div><div class="et_pb_module et_pb_code et_pb_code_0">
				
				
				
				
				
			</div>
			</div>
				
				
				
				
			</div>
				
				
			</div></p>
<p>The post <a rel="nofollow" href="https://qilin.cloud/streamline-event-driven-microservices-with-kafka-and-python/">Streamline event-driven microservices with Kafka and Python</a> appeared first on <a rel="nofollow" href="https://qilin.cloud">Qilin.Cloud</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://qilin.cloud/streamline-event-driven-microservices-with-kafka-and-python/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Trunk-based Development</title>
		<link>https://qilin.cloud/trunk-based-development/</link>
					<comments>https://qilin.cloud/trunk-based-development/#comments</comments>
		
		<dc:creator><![CDATA[Marc Costea]]></dc:creator>
		<pubDate>Thu, 08 Jun 2023 08:01:15 +0000</pubDate>
				<category><![CDATA[Uncategorized]]></category>
		<guid isPermaLink="false">https://qilin.cloud/?p=601</guid>

					<description><![CDATA[<p>A source-control branching model, where developers collaborate on code in a single branch called ‘trunk’ *, resist any pressure to create other long-lived development branches by employing documented techniques. They therefore avoid merge hell, do not break the build, and live happily ever after.</p>
<p>The post <a rel="nofollow" href="https://qilin.cloud/trunk-based-development/">Trunk-based Development</a> appeared first on <a rel="nofollow" href="https://qilin.cloud">Qilin.Cloud</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><div class="et_pb_section et_pb_section_4 et_section_regular" >
				
				
				
				
				
				
				<div class="et_pb_row et_pb_row_22">
				<div class="et_pb_column et_pb_column_4_4 et_pb_column_22  et_pb_css_mix_blend_mode_passthrough et-last-child">
				
				
				
				
				<div class="et_pb_module et_pb_text et_pb_text_46  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><!-- divi:paragraph --></p>
<p>In order to develop quality software, we need to be able to track all changes and reverse them if necessary. Version control systems fill that role by tracking project history and helping to merge changes made by multiple people. They greatly speed up work and give us the ability to find bugs more easily.</p>
<p><!-- /divi:paragraph --></p>
<p><!-- divi:paragraph --></p>
<p>Moreover, working in distributed teams is possible mainly thanks to these tools. They enable several people to work on different parts of a project at the same time and later join their results into a single product. Let’s take a closer look at version control systems and explain how trunk based development and Git flow came to being.</p>
<p><!-- /divi:paragraph --></p>
<p><!-- divi:paragraph --></p>
<p><!-- /divi:paragraph --></div>
			</div><div class="et_pb_module et_pb_text et_pb_text_47  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><h2>Git Flow vs. Trunk: How Version Control Systems Changed the World</h2>
<p>&nbsp;</p>
<p>Before version control systems were created, people relied on manually backing up previous versions of projects. They were copying modified files by hand in order to incorporate the work of multiple developers on the same project.</p>
<p>It cost a lot of time, hard drive space, and money.</p>
<p>When we<span> </span>look at the history, we can broadly distinguish three generations of version control software.</p>
<p>Let’s take a look at them:</p>
<h4>First Generation:</h4>
<table border="1" style="border-collapse: collapse; width: 100%;">
<tbody>
<tr>
<td style="width: 50%;">Operations</td>
<td style="width: 50%;">On a singel file only</td>
</tr>
<tr>
<td style="width: 50%;">Concurrency</td>
<td style="width: 50%;">Locks</td>
</tr>
<tr>
<td style="width: 50%;">Networking</td>
<td style="width: 50%;">Centralized</td>
</tr>
<tr>
<td style="width: 50%;">Examples</td>
<td style="width: 50%;">RCS</td>
</tr>
</tbody>
</table>
<h4>Second Generation:</h4>
<table border="1" style="border-collapse: collapse; width: 100%;">
<tbody>
<tr>
<td style="width: 50%;">Operations</td>
<td style="width: 50%;">On multiple files</td>
</tr>
<tr>
<td style="width: 50%;">Concurrency</td>
<td style="width: 50%;">Merge before commit</td>
</tr>
<tr>
<td style="width: 50%;">Networking</td>
<td style="width: 50%;">Centralized</td>
</tr>
<tr>
<td style="width: 50%;">Examples</td>
<td style="width: 50%;">Subversion, CVS</td>
</tr>
</tbody>
</table>
<h4>Third Generation:</h4>
<table border="1" style="border-collapse: collapse; width: 100%;">
<tbody>
<tr>
<td style="width: 50%;">Operations</td>
<td style="width: 50%;">On multiple files</td>
</tr>
<tr>
<td style="width: 50%;">Concurrency</td>
<td style="width: 50%;">Commit before merge</td>
</tr>
<tr>
<td style="width: 50%;">Networking</td>
<td style="width: 50%;">Distributed</td>
</tr>
<tr>
<td style="width: 50%;">Examples</td>
<td style="width: 50%;">Git, Mercurial</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>We notice that as version control systems mature, there is a tendency to increase the ability to work on projects in parallel.</p>
<p>One of the most groundbreaking changes was a shift from locking files to merging changes instead. It enabled programmers to work more efficiently.</p>
<p>Another considerable improvement was the introduction of distributed systems.<span> </span><a href="https://git-scm.com/book/en/v2/Getting-Started-A-Short-History-of-Git" target="_blank" rel="noopener">Git was one of the first</a><span> </span>tools to incorporate this philosophy. It literally enabled the open-source world to flourish. Git allows developers to copy the whole repository, in an operation called forking, and introduce the desired changes without needing to worry about merge conflicts.</p>
<p>Later, they can start a pull request in order to merge their changes into the original project. If the initial developer is not interested in incorporating those changes from other repositories, then they can turn them into separate projects on their own. It’s all possible thanks to the fact that there is no concept of central storage.</p></div>
			</div><div class="et_pb_module et_pb_text et_pb_text_48  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><h2></h2>
<h2 id="development-styles">Development Styles</h2>
<p>&nbsp;</p>
<p>Nowadays, the most popular version control system is definitely Git, with a market share of about 70 percent in 2016.</p>
<p>Git was popularized with the rise of Linux and the open-source scene in general.<span> </span><a href="https://github.com/" target="_blank" rel="noopener">GitHub</a>, currently the most popular online storage for public projects, was also a considerable contributor to its prevalence. We owe the introduction of easy to manage pull requests to Git.</p>
<p>Put simply, pull requests are requests created by a software developer to combine changes they created with the main project. It includes a process of reviewing those changes. Reviewers can insert comments on every bit they think could be improved, or see as unnecessary.</p>
<p>After receiving feedback, the creator can respond to it, creating a discussion, or simply follow it and change their code accordingly.</p></div>
			</div><div class="et_pb_module et_pb_image et_pb_image_8">
				
				
				
				
				<a href="https://qilin.cloud/wp-content/uploads/2023/08/blog1-1.png" class="et_pb_lightbox_image" title=""><span class="et_pb_image_wrap "><img loading="lazy" decoding="async" width="1268" height="853" src="https://qilin.cloud/wp-content/uploads/2023/08/blog1-1.png" alt="blog1 1" title="blog1-1" srcset="https://qilin.cloud/wp-content/uploads/2023/08/blog1-1.png 1268w, https://qilin.cloud/wp-content/uploads/2023/08/blog1-1-980x659.png 980w, https://qilin.cloud/wp-content/uploads/2023/08/blog1-1-480x323.png 480w" sizes="(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 1268px, 100vw" class="wp-image-686"></span></a>
			</div><div class="et_pb_module et_pb_text et_pb_text_49  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><p>Git is merely a tool. You can use it in many different ways. Currently, two most popular development styles you can encounter are<span> </span><a href="https://github.com/nvie/gitflow" target="_blank" rel="noopener">Git flow</a><span> </span>and<span> </span><a href="https://trunkbaseddevelopment.com/" target="_blank" rel="noopener">trunk-based development</a>. Quite often, people are familiar with one of those styles and they might neglect the other one.</p>
<p>Let’s take a closer look at<span> </span><em>both of them</em><span> </span>in a trunk-based vs. Git flow comparison and learn how and when we should use them.</p></div>
			</div><div class="et_pb_module et_pb_text et_pb_text_50  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><h2></h2>
<h2 id="git-flow">Git Flow</h2>
<p>&nbsp;</p>
<p>In the Git flow development model, you have one main development branch with strict access to it. It’s often called the<span> </span><code>develop</code><span> </span>branch.</p>
<p>Developers create feature branches from this main branch and work on them. Once they are done, they create pull requests. In pull requests, other developers comment on changes and may have discussions, often quite lengthy ones.</p>
<p>It takes some time to agree on a final version of changes. Once it’s agreed upon, the pull request is accepted and merged to the main branch. Once it’s decided that the main branch has reached enough maturity to be released, a separate branch is created to prepare the final version. The application from this Git branch is tested and bug fixes are applied up to the moment that it’s ready to be published to final users. Once that is done, we merge the final product to the<span> </span><code>master</code><span> </span>branch and tag it with the release version. In the meantime, new features can be developed on the<span> </span><code>develop</code><span> </span>branch.</p>
<p>Below, you can see a Git flow branching diagram, depicting a general Git process flow:</p></div>
			</div><div class="et_pb_module et_pb_image et_pb_image_9">
				
				
				
				
				<span class="et_pb_image_wrap "><img loading="lazy" decoding="async" width="603" height="897" src="https://qilin.cloud/wp-content/uploads/2023/08/blog1-2.png" alt="blog1 2" title="blog1-2" srcset="https://qilin.cloud/wp-content/uploads/2023/08/blog1-2.png 603w, https://qilin.cloud/wp-content/uploads/2023/08/blog1-2-480x714.png 480w" sizes="(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 603px, 100vw" class="wp-image-688"></span>
			</div><div class="et_pb_module et_pb_text et_pb_text_51  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><p>One of the advantages of Git flow is strict control. Only authorized developers can approve changes after looking at them closely. It ensures code quality and helps eliminate bugs early.</p>
<p>However, you need to remember that it can also be a huge disadvantage. It creates a funnel slowing down software development. If speed is your primary concern, then it might be a serious problem. Features developed separately can create long-living branches that might be hard to combine with the main project.</p>
<p>What’s more, pull requests focus code review solely on new code. Instead of looking at code as a whole and working to improve it as such, they check only newly introduced changes. In some cases, they might lead to<span> </span>premature optimization<span> </span>since it’s always possible to implement something to perform faster.</p>
<p>Moreover, pull requests might lead to extensive micromanagement, where the lead developer literally manages every single line of code. If you have experienced developers you can trust, they can handle it, but you might be wasting their time and skills. It can also severely de-motivate developers.</p>
<p>In larger organizations, office politics during pull requests are another concern. It is conceivable that people who approve pull requests might use their position to purposefully block certain developers from making any changes to the code base. They could do this due to a lack of confidence, while some may abuse their position to settle personal scores.</p></div>
			</div><div class="et_pb_module et_pb_text et_pb_text_52  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><h2></h2>
<h2 id="git-flow-pros-and-cons">Git Flow Pros and Cons</h2>
<p>As you can see, doing pull requests might not always be the best choice. They should be used where appropriate only.</p>
<p>&nbsp;</p>
<h3 id="when-does-git-flow-work-best">When Does Git Flow Work Best?</h3>
<ul>
<li>
<p><strong>When you run an open-source project.</strong><br />This style comes from the open-source world and it works best there. Since everyone can contribute, you want to have very strict access to all the changes. You want to be able to check every single line of code, because frankly you can’t trust people contributing. Usually, those are not commercial projects, so development speed is not a concern.</p>
</li>
<li>
<p><strong>When you have a lot of junior developers.</strong><br />If you work mostly with junior developers, then you want to have a way to check their work closely. You can give them multiple hints on how to do things more efficiently and help them improve their skills faster. People who accept pull requests have strict control over recurring changes so they can prevent deteriorating code quality.</p>
</li>
<li>
<p><strong>When you have an established product.</strong><br />This style also seems to play well when you already have a successful product. In such cases, the focus is usually on application performance and load capabilities. That kind of optimization requires very precise changes. Usually, time is not a constraint, so this style works well here. What’s more, large enterprises are a great fit for this style. They need to control every change closely, since they don’t want to break their multi-million dollar investment.</p>
</li>
</ul>
<h3 id="when-can-git-flow-cause-problems">When Can Git Flow Cause Problems?</h3>
<ul>
<li>
<p><strong>When you are just starting up.</strong><br />If you are just starting up, then Git flow is not for you. Chances are you want to create a minimal viable product quickly. Doing pull requests creates a huge bottleneck that slows the whole team down dramatically. You simply can’t afford it. The problem with Git flow is the fact that pull requests can take a lot of time. It’s just not possible to provide rapid development that way.</p>
</li>
<li>
<p><strong>When you need to iterate quickly.</strong><br />Once you reach the first version of your product, you will most likely need to pivot it few times to meet your customers’ need. Again, multiple branches and pull requests reduce development speed dramatically and are not advised in such cases.</p>
</li>
<li>
<p><strong>When you work mostly with senior developers.</strong><br />If your team consists mainly of senior developers who have worked with one another for a longer period of time, then you don’t really need the aforementioned pull request micromanagement. You trust your developers and know that they are professionals. Let them do their job and don’t slow them down with all the Git flow bureaucracy.</p>
</li>
</ul></div>
			</div><div class="et_pb_module et_pb_text et_pb_text_53  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><h2 id="trunk-based-development-workflow">Trunk-based Development Workflow</h2>
<p>&nbsp;</p>
<p>In the trunk-based development model, all developers work on a single branch with open access to it. Often it’s simply the<span> </span><code>master</code><span> </span>branch. They commit code to it and run it. It’s super simple.</p>
<p>In some cases, they create short-lived feature branches. Once code on their branch compiles and passess all tests, they merge it straight to<span> </span><code>master</code>. It ensures that development is truly continuous and prevents developers from creating merge conflicts that are difficult to resolve.</p>
<p>Let’s have a look at trunk-based development workflow.</p></div>
			</div><div class="et_pb_module et_pb_image et_pb_image_10">
				
				
				
				
				<span class="et_pb_image_wrap "><img loading="lazy" decoding="async" width="469" height="914" src="https://qilin.cloud/wp-content/uploads/2023/08/bild1-3.png" alt="bild1 3" title="bild1-3" srcset="https://qilin.cloud/wp-content/uploads/2023/08/bild1-3.png 469w, https://qilin.cloud/wp-content/uploads/2023/08/bild1-3-154x300.png 154w" sizes="(max-width: 469px) 100vw, 469px" class="wp-image-689"></span>
			</div><div class="et_pb_module et_pb_text et_pb_text_54  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><p>The only way to review code in such an approach is to do full source code review. Usually, lengthy discussions are limited. No one has strict control over what is being modified in the source code base—that is why it’s important to have enforceable code style in place. Developers that work in such style should be experienced so that you know they won’t lower source code quality.</p>
<p>This style of work can be great when you work with a team of<span> </span>seasoned software developers. It enables them to introduce new improvements quickly and without unnecessary bureaucracy. It also shows them that you trust them, since they can introduce code straight into the<span> </span><code>master</code><span> </span>branch. Developers in this workflow are very autonomous—they are delivering directly and are checked on final results in the working product. There is definitely much less micromanagement and possibility for office politics in this method.</p>
<p>If, on the other hand, you do not have a seasoned team or you don’t trust them for some reason, you shouldn’t go with this method—you should choose Git flow instead. It will save you unnecessary worries.</p></div>
			</div><div class="et_pb_module et_pb_text et_pb_text_55  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><h2></h2>
<h2 id="pros-and-cons-of-trunk-based-development">Pros and Cons of Trunk-based Development</h2>
<p>Let’s take a closer look at both sides of the cost—the very best and very worst scenarios.</p>
<p>&nbsp;</p>
<h3 id="when-does-trunk-based-development-work-best">When Does Trunk-based Development Work Best?</h3>
<ul>
<li>
<p><strong>When you are just starting up.</strong><br />If you are working on your minimum viable product, then this style is perfect for you. It offers maximum development speed with minimum formality. Since there are no pull requests, developers can deliver new functionality at the speed of light. Just be sure to hire experienced programmers.</p>
</li>
<li>
<p><strong>When you need to iterate quickly.</strong><br />Once you reached the first version of your product and you noticed that your customers want something different, then don’t think twice and use this style to pivot into a new direction. You are still in the exploration phase and you need to be able to change your product as fast as possible.</p>
</li>
<li>
<p><strong>When you work mostly with senior developers.</strong><br />If your team consists mainly of senior developers, then you should trust them and let them do their job. This workflow gives them the autonomy that they need and enables them to wield their mastery of their profession. Just give them purpose (tasks to accomplish) and watch how your product grows.</p>
</li>
</ul>
<h3 id="when-can-trunk-based-development-cause-problems">When Can Trunk-based Development Cause Problems?</h3>
<ul>
<li>
<p><strong>When you run an open-source project.</strong><br />If you are running an open-source project, then Git flow is the better option. You need very strict control over changes and you can’t trust contributors. After all, anyone can contribute. Including online trolls.</p>
</li>
<li>
<p><strong>When you have a lot of junior developers.</strong><br />If you hire mostly junior developers, then it’s a better idea to tightly control what they are doing. Strict pull requests will help them to to improve their skills and will find potential bugs more quickly.</p>
</li>
<li>
<p><strong>When you have established product or manage large teams.</strong><br />If you already have a prosperous product or manage large teams at a huge enterprise, then Git flow might be a better idea. You want to have strict control over what is happening with a well-established product worth millions of dollars. Probably, application performance and load capabilities are the most important things. That kind of optimization requires very precise changes.</p>
</li>
</ul></div>
			</div><div class="et_pb_module et_pb_text et_pb_text_56  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><h2 id="use-the-right-tool-for-the-right-job">Use the Right Tool for the Right Job</h2>
<p>&nbsp;</p>
<p>As I said before, Git is just a tool. Like every other tool, it needs to be used appropriately.</p>
<p>Git flow manages all changes through pull requests. It provides strict access control to all changes. It’s great for open-source projects, large enterprises, companies with established products, or a team of inexperienced junior developers. You can safely check what is being introduced into the source code. On the other hand, it might lead to extensive micromanagement, disputes involving office politics, and significantly slower development.</p>
<p>Trunk-based development gives programmers full autonomy and expresses more faith in them and their judgment. Access to source code is free, so you really need to be able to trust your team. It provides excellent software development speed and reduces processes. These factors make it perfect when creating new products or pivoting an existing application in an all-new direction. It works wonders if you work mostly with experienced developers.</p>
<p>Still, if you work with junior programmers or people you don’t fully trust, Git flow is a much better alternative.</p>
<p>Equipped with this knowledge, I hope you will be able to choose the workflow that perfectly matches your project.</p></div>
			</div><div class="et_pb_module et_pb_video et_pb_video_0">
				
				
				
				
				<div class="et_pb_video_box"><iframe loading="lazy" title="Our journey from Gitflow to Trunk Based Development • Ludovic Toison • Devoxx Poland 2023" width="1080" height="608" src="https://www.youtube.com/embed/WU3F5b-LbII?feature=oembed"  allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div>
				
			</div>
			</div>
				
				
				
				
			</div>
				
				
			</div></p>
<p>The post <a rel="nofollow" href="https://qilin.cloud/trunk-based-development/">Trunk-based Development</a> appeared first on <a rel="nofollow" href="https://qilin.cloud">Qilin.Cloud</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://qilin.cloud/trunk-based-development/feed/</wfw:commentRss>
			<slash:comments>10</slash:comments>
		
		
			</item>
	</channel>
</rss>
