<?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>Product Updates | Qilin.Cloud</title>
	<atom:link href="https://qilin.cloud/category/product-updates/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>Product Updates | 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>Pipeline Testing Mode: Pinned Data and Deterministic Debugging for Integrations</title>
		<link>https://qilin.cloud/pipeline-testing-mode-pinned-data-deterministic-debugging/</link>
		
		<dc:creator><![CDATA[Dinh Vo]]></dc:creator>
		<pubDate>Sat, 31 Jan 2026 08:00:00 +0000</pubDate>
				<category><![CDATA[Product Updates]]></category>
		<category><![CDATA[debugging]]></category>
		<category><![CDATA[deterministic]]></category>
		<category><![CDATA[developer experience]]></category>
		<category><![CDATA[pipelines]]></category>
		<category><![CDATA[testing]]></category>
		<guid isPermaLink="false">https://qilin.cloud/?p=3744</guid>

					<description><![CDATA[<p>January’s update introduces Testing Mode in the Pipeline Builder: run deterministic tests with pinned data, replay processors with historical context, and debug integrations without poking production systems.</p>
<p>The post <a rel="nofollow" href="https://qilin.cloud/pipeline-testing-mode-pinned-data-deterministic-debugging/">Pipeline Testing Mode: Pinned Data and Deterministic Debugging for Integrations</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>Every integration engineer has done this dance:</p>
<ul>
<li>change a mapping</li>
<li>run the pipeline</li>
<li>wait</li>
<li>see a failure</li>
<li>change a field</li>
<li>run again</li>
<li>wait again</li>
<li>discover the failure is in a completely different step</li>
</ul>
<p>It’s not that we love it. It’s just how pipelines have traditionally been tested: <em>in production-like conditions, with real dependencies, and a lot of luck.</em></p>
<p>January’s update is about replacing luck with something more respectable:</p>
<p><strong>Testing Mode in the Pipeline Builder</strong> — powered by <strong>Pinned Data</strong>.</p></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='#WhatisTestingMode' data-hl='2'></span><a href='#WhatisTestingMode' id='WhatisTestingMode_toc_headding'>What is Testing Mode?</a></div></li><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#PinnedDatatheconceptsimpleandpowerful' data-hl='2'></span><a href='#PinnedDatatheconceptsimpleandpowerful' id='PinnedDatatheconceptsimpleandpowerful_toc_headding'>Pinned Data: the concept (simple and powerful)</a></div></li><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#Threetestingscenariossoyoucantestlikeagrownup' data-hl='2'></span><a href='#Threetestingscenariossoyoucantestlikeagrownup' id='Threetestingscenariossoyoucantestlikeagrownup_toc_headding'>Three testing scenarios (so you can test like a grown-up)</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='#1Testthefullpipelineendtoendwithpinnedentrydata' data-hl='3'></span><a href='#1Testthefullpipelineendtoendwithpinnedentrydata' id='1Testthefullpipelineendtoendwithpinnedentrydata_toc_headding'>1) Test the full pipeline end-to-end (with pinned entry data)</a></div></li><li class="pac_dtoc_li_heading_level_3" role="treeitem" ><div role="presentation" ><span data-href='#2Testasingleprocessorusingrealhistoricalcontext' data-hl='3'></span><a href='#2Testasingleprocessorusingrealhistoricalcontext' id='2Testasingleprocessorusingrealhistoricalcontext_toc_headding'>2) Test a single processor using real historical context</a></div></li><li class="pac_dtoc_li_heading_level_3" role="treeitem" ><div role="presentation" ><span data-href='#3Testaprocessorinisolationnohistoricalcontextneeded' data-hl='3'></span><a href='#3Testaprocessorinisolationnohistoricalcontextneeded' id='3Testaprocessorinisolationnohistoricalcontextneeded_toc_headding'>3) Test a processor in isolation (no historical context needed)</a></div></li></ul><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#AveryrealusecasetestenrichmentwithoutcallingthepricingAPI' data-hl='2'></span><a href='#AveryrealusecasetestenrichmentwithoutcallingthepricingAPI' id='AveryrealusecasetestenrichmentwithoutcallingthepricingAPI_toc_headding'>A very real use case: “test enrichment without calling the pricing API”</a></div></li><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#Whythismattersespeciallytoagencies' data-hl='2'></span><a href='#Whythismattersespeciallytoagencies' id='Whythismattersespeciallytoagencies_toc_headding'>Why this matters (especially to agencies)</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='#Formerchantsandinvestors' data-hl='2'></span><a href='#Formerchantsandinvestors' id='Formerchantsandinvestors_toc_headding'>For merchants and investors</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='#Testingshouldntrequirebravery' data-hl='2'></span><a href='#Testingshouldntrequirebravery' id='Testingshouldntrequirebravery_toc_headding'>Testing shouldn’t require bravery</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_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>What is Testing Mode?</span></h2>
						<div class="et_pb_blurb_description"><p>Testing Mode lets you run pipeline logic <strong>without affecting actual pipeline execution</strong>.</p>
<p>That means you can validate:</p>
<ul>
<li>routing</li>
<li>filtering</li>
<li>enrichment</li>
<li>merge behavior</li>
<li>connector payload structure</li>
</ul>
<p>…without accidentally pushing real updates to a marketplace or polluting production logs with “test objects”.</p>
<p>The results are still observable (tracked like normal executions), but they’re flagged as test runs.</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_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>Pinned Data: the concept (simple and powerful)</span></h2>
						<div class="et_pb_blurb_description"><p>Pinned Data is a mechanism that replaces the live output of a processor with fixed mock data.</p>
<p>In normal runs:</p>
<ul>
<li>a processor does its real job (HTTP call, connector sync, etc.)</li>
<li>output depends on external systems, network, timing</li>
</ul>
<p>In test runs with pinned data:</p>
<ul>
<li>the processor’s real work is skipped</li>
<li>the output becomes deterministic</li>
<li>downstream steps can be tested with certainty</li>
</ul>
<p>This is the classic integration engineer’s dream:</p>
<blockquote>
<p><em><strong>&gt; “Let me test the next steps, even if the external API is flaky today.”</strong></em></p>
</blockquote></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>Three testing scenarios (so you can test like a grown-up)</span></h2>
						<div class="et_pb_blurb_description"><h3>1) Test the full pipeline end-to-end (with pinned entry data)</h3>
<p>You provide pinned data for the entry processor, simulating the trigger object.</p>
<p>Result: the pipeline runs end-to-end on a controlled input, producing deterministic outputs.</p>
<h3>2) Test a single processor using real historical context</h3>
<p>You provide a previous Pipeline Execution ID.</p>
<p>Qilin loads the execution context from that run and re-executes only the processor you’re testing.</p>
<p>This is perfect when:</p>
<ul>
<li>you changed an enrichment rule</li>
<li>you adjusted a filter predicate</li>
<li>you want to replay one step against real production-like data</li>
</ul>
<h3>3) Test a processor in isolation (no historical context needed)</h3>
<p>You provide pinned input directly for the processor.</p>
<p>Result: fast, isolated, great for validating configs and behavior without waiting for upstream steps.</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.</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_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>A very real use case: “test enrichment without calling the pricing API”</span></h2>
						<div class="et_pb_blurb_description"><p>You want to verify enrichment logic that depends on a pricing service.</p>
<p>But the pricing API is unstable today.</p>
<p>Pinned data lets you fake the pricing output so you can test:</p>
<ul>
<li>calculations</li>
<li>mapping</li>
<li>downstream connector payloads</li>
</ul>
<p>No external dependency. No waiting. No chaos.</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>Why this matters (especially to agencies)</span></h2>
						<div class="et_pb_blurb_description"><p>Agencies live and die by delivery speed and reliability.</p>
<p>Testing Mode enables a cleaner workflow:</p>
<ul>
<li>build pipeline logic</li>
<li>test with pinned scenarios</li>
<li>validate edge cases</li>
<li>only then turn on live execution</li>
</ul>
<p>That’s how you reduce go-live risk without multiplying custom tooling.</p></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_28  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"><ul>
<li>deterministic tests for pipeline logic</li>
<li>faster iteration loops</li>
<li>easier debugging (“same input, same output”)</li>
<li>safer experimentation with advanced processors (merge, switch-case, enrichment, http calls)</li>
</ul></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_29  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 and investors</span></h2>
						<div class="et_pb_blurb_description"><ul>
<li>fewer production incidents caused by “untested config changes”</li>
<li>faster onboarding because pipelines can be validated before real data flows</li>
<li>stronger platform trust: changes are intentional and verifiable</li>
</ul></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_30  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>February will continue the “operational control” theme:</p>
<ul>
<li>expanded UI management for queue storage and credentials</li>
<li>more advanced routing and processor configuration in the portal</li>
</ul>
<p>Because once pipelines grow, operations needs knobs &#8211; not prayers.</p></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_31  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>Testing shouldn’t require bravery</span></h2>
						<div class="et_pb_blurb_description"><p>The traditional way of testing pipelines is stressful because it mixes two activities:</p>
<ul>
<li>validating logic</li>
<li>operating production</li>
</ul>
<p>Testing Mode separates them.</p>
<p>And honestly? That’s long overdue.</p></div>
					</div>
				</div>
			</div>
			</div>
				
				
				
				
			</div>
				
				
			</div>
<p>The post <a rel="nofollow" href="https://qilin.cloud/pipeline-testing-mode-pinned-data-deterministic-debugging/">Pipeline Testing Mode: Pinned Data and Deterministic Debugging for Integrations</a> appeared first on <a rel="nofollow" href="https://qilin.cloud">Qilin.Cloud</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Kaufland Offer Sync (Update-Only): The Safe Way to Keep Price and Stock Fresh</title>
		<link>https://qilin.cloud/kaufland-offer-sync-update-only-safe-price-stock/</link>
		
		<dc:creator><![CDATA[Tuyen Nguyen]]></dc:creator>
		<pubDate>Wed, 31 Dec 2025 08:00:00 +0000</pubDate>
				<category><![CDATA[Product Updates]]></category>
		<category><![CDATA[kaufland]]></category>
		<category><![CDATA[marketplace]]></category>
		<category><![CDATA[offer sync]]></category>
		<category><![CDATA[price]]></category>
		<category><![CDATA[stock]]></category>
		<guid isPermaLink="false">https://qilin.cloud/?p=3738</guid>

					<description><![CDATA[<p>December’s connector milestone: update-only Kaufland offer sync. Clean identification (EAN + condition + storefront), safe updates for price/stock/handling time, and batch exports for real-world volume.</p>
<p>The post <a rel="nofollow" href="https://qilin.cloud/kaufland-offer-sync-update-only-safe-price-stock/">Kaufland Offer Sync (Update-Only): The Safe Way to Keep Price and Stock Fresh</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>Commerce marketplaces are not playgrounds.</p>
<p>If you’ve integrated with them long enough, you learn a cautious habit:</p>
<p><strong>Never create or overwrite things by accident.</strong></p>
<p>December’s connector work embraces that cautious, battle-earned mindset with an important milestone:</p>
<p><strong>Kaufland Connector (Update-Only Offer Sync)</strong></p>
<p>At this stage, the connector focuses on the safest and most operationally valuable capability first:</p>
<ul>
<li>updating existing offers (units) for:
<ul>
<li><strong>price</strong></li>
<li><strong>stock</strong></li>
<li><strong>handling time</strong></li>
</ul>
</li>
</ul>
<p>No surprise creations. No accidental duplication. Just clean, controlled updates.</p></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 pac_divi_table_of_contents pac_divi_table_of_contents_2">
				
				
				
				
				
				
				<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='#Whyupdateonlyisafeaturenotalimitation' data-hl='2'></span><a href='#Whyupdateonlyisafeaturenotalimitation' id='Whyupdateonlyisafeaturenotalimitation_toc_headding'>Why “update-only” is a feature, not a limitation</a></div></li><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#HowQilinidentifiesanexistingKauflandoffer' data-hl='2'></span><a href='#HowQilinidentifiesanexistingKauflandoffer' id='HowQilinidentifiesanexistingKauflandoffer_toc_headding'>How Qilin identifies an existing Kaufland offer</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='#Behavior' data-hl='3'></span><a href='#Behavior' id='Behavior_toc_headding'> Behavior</a></div></li></ul><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#Howtopushofferssinglevsbatch' data-hl='2'></span><a href='#Howtopushofferssinglevsbatch' id='Howtopushofferssinglevsbatch_toc_headding'>How to push offers: single vs batch</a></div></li><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#Bestpracticesthedonthateyourselflateredition' data-hl='2'></span><a href='#Bestpracticesthedonthateyourselflateredition' id='Bestpracticesthedonthateyourselflateredition_toc_headding'>Best practices (the “don’t hate yourself later” edition)</a></div></li><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#Whobenefits' data-hl='2'></span><a href='#Whobenefits' id='Whobenefits_toc_headding'>Who benefits?</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='#Developers' data-hl='3'></span><a href='#Developers' id='Developers_toc_headding'>Developers</a></div></li><li class="pac_dtoc_li_heading_level_3" role="treeitem" ><div role="presentation" ><span data-href='#Merchants' data-hl='3'></span><a href='#Merchants' id='Merchants_toc_headding'>Merchants</a></div></li><li class="pac_dtoc_li_heading_level_3" role="treeitem" ><div role="presentation" ><span data-href='#Agencies' data-hl='3'></span><a href='#Agencies' id='Agencies_toc_headding'>Agencies</a></div></li><li class="pac_dtoc_li_heading_level_3" role="treeitem" ><div role="presentation" ><span data-href='#Investors' data-hl='3'></span><a href='#Investors' id='Investors_toc_headding'>Investors</a></div></li></ul><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='#Marketplaceintegrationsrewardcaution' data-hl='2'></span><a href='#Marketplaceintegrationsrewardcaution' id='Marketplaceintegrationsrewardcaution_toc_headding'>Marketplace integrations reward caution</a></div></li></ul></div>
            </div>
        </div>
        
				</div>
			</div>
			</div>
				
				
				
				
			</div><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_blurb et_pb_blurb_39  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 “update-only” is a feature, not a limitation</span></h2>
						<div class="et_pb_blurb_description"><p>In marketplaces, “create” is risky.</p>
<p>It’s easy to create the wrong offer with:</p>
<ul>
<li>the wrong condition</li>
<li>the wrong storefront</li>
<li>missing compliance fields</li>
<li>the wrong EAN mapping</li>
<li>inconsistent identifiers</li>
</ul>
<p>Those mistakes can be expensive.</p>
<p>So update-only sync is the disciplined, traditional approach:</p>
<p><em><strong>&gt; First, prove you can update reliably. Then expand scope.</strong></em></p></div>
					</div>
				</div>
			</div>
			</div>
				
				
				
				
			</div><div class="et_pb_row et_pb_row_23">
				<div class="et_pb_column et_pb_column_4_4 et_pb_column_23  et_pb_css_mix_blend_mode_passthrough et-last-child">
				
				
				
				
				<div class="et_pb_module et_pb_blurb et_pb_blurb_40  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>How Qilin identifies an existing Kaufland offer</span></h2>
						<div class="et_pb_blurb_description"><p>In Kaufland, an offer (unit) is uniquely identified by the combination:</p>
<p><strong>**EAN + Condition + Storefront**</strong></p>
<p>That means the connector looks at these three pieces of information to locate the existing unit.</p>
<h3> Behavior</h3>
<ul>
<li><strong>If a matching unit is found</strong> → update price/stock/handling time</li>
<li><strong>If no matching unit is found</strong> → mark the sync as failed with:
<ul>
<li>`Cannot find existing offer`</li>
</ul>
</li>
</ul>
<p>This is the correct kind of strictness. It prevents “phantom offers” from appearing because a mapping was wrong.</p></div>
					</div>
				</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">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_41  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>How to push offers: single vs batch</span></h2>
						<div class="et_pb_blurb_description"><p>You can export offers using either:</p>
<ul>
<li>`OutputConnector` (single item)</li>
<li>`OutputConnectorByBatch` (bulk)</li>
</ul>
<p>Batch mode supports up to <strong>150 offers per batch</strong>, which is ideal for real-world offer volume and helps reduce request overhead.</p>
<p>A high-level flow looks like:</p>
<ol>
<li>build a pipeline that produces Offer objects</li>
<li>add an output processor (single or batch)</li>
<li>configure a `targetId` that represents the Kaufland storefront destination</li>
<li>onboard the channel using that same `targetId` so the connector knows where to send updates</li>
</ol>
<p>This keeps the pipeline definition and the channel onboarding aligned &#8211; no hidden mapping magic.</p></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_42  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>Best practices (the “don’t hate yourself later” edition)</span></h2>
						<div class="et_pb_blurb_description"><ul>
<li>Always include valid <strong>EAN</strong> and <strong>Condition</strong> on offers. They’re mandatory for correct unit matching.</li>
<li>Treat `targetId` as a stable contract. If it changes, your connector routing changes.</li>
<li>Prefer batch export for high-volume updates. It’s cheaper, faster, and friendlier to APIs.</li>
<li>Use Data Flow Tracking to monitor failures and spot “offer not found” patterns early &#8211; those usually indicate mapping issues.</li>
</ul></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_43  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>Who benefits?</span></h2>
						<div class="et_pb_blurb_description"><h3>Developers</h3>
<ul>
<li>clear identification logic (less ambiguity)</li>
<li>safer connector behavior (less risk during rollout)</li>
<li>batch export for operational throughput</li>
</ul>
<h3>Merchants</h3>
<ul>
<li>safer price/stock updates without accidental new offers</li>
<li>predictable behavior under load</li>
<li>cleaner error signals when something isn’t mapped correctly</li>
</ul>
<h3>Agencies</h3>
<ul>
<li>easier rollout strategy: start with updates, validate matching logic, then scale</li>
<li>fewer marketplace “oops moments” during go-live</li>
</ul>
<h3>Investors</h3>
<p>Connector depth expands addressable value. Update-only is a reliable first step toward full lifecycle sync while keeping risk low.</p></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_44  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>January will focus on the developer and operations experience again:</p>
<p><strong>pipeline testing mode</strong> and expanded UI capabilities &#8211; so teams can validate flows safely before turning them loose on production channels.</p></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_45  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>Marketplace integrations reward caution</span></h2>
						<div class="et_pb_blurb_description"><p>Fast and reckless breaks things.</p>
<p>Slow and deliberate builds trust.</p>
<p>Qilin.Cloud is taking the deliberate path &#8211; because that’s how integrations survive in the real world.</p></div>
					</div>
				</div>
			</div>
			</div>
				
				
				
				
			</div>
				
				
			</div>
<p>The post <a rel="nofollow" href="https://qilin.cloud/kaufland-offer-sync-update-only-safe-price-stock/">Kaufland Offer Sync (Update-Only): The Safe Way to Keep Price and Stock Fresh</a> appeared first on <a rel="nofollow" href="https://qilin.cloud">Qilin.Cloud</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Error Handling &#038; Manual Retry: Recovering from Failures Like a Grown-Up Platform</title>
		<link>https://qilin.cloud/error-handling-manual-retry-recover-like-grown-up-platform/</link>
		
		<dc:creator><![CDATA[Man T. Huu]]></dc:creator>
		<pubDate>Sun, 30 Nov 2025 08:00:00 +0000</pubDate>
				<category><![CDATA[Product Updates]]></category>
		<category><![CDATA[data flow tracking]]></category>
		<category><![CDATA[error handling]]></category>
		<category><![CDATA[manual retry]]></category>
		<category><![CDATA[operations]]></category>
		<category><![CDATA[resilience]]></category>
		<guid isPermaLink="false">https://qilin.cloud/?p=3730</guid>

					<description><![CDATA[<p>November’s update strengthens operational maturity: nuanced error statuses, continue/stop policies, manual retry for executions, and reproducibility safeguards so recovery is controlled—not chaotic.</p>
<p>The post <a rel="nofollow" href="https://qilin.cloud/error-handling-manual-retry-recover-like-grown-up-platform/">Error Handling &amp; Manual Retry: Recovering from Failures Like a Grown-Up Platform</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_3 et_section_regular" >
				
				
				
				
				
				
				<div class="et_pb_row et_pb_row_24">
				<div class="et_pb_column et_pb_column_4_4 et_pb_column_24  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"><p>Every integration platform eventually faces the same moment.</p>
<p>A pipeline fails in production.</p>
<p>Not in a “dev environment” way. <br />In a “customers are waiting and the marketplace clock is ticking” way.</p>
<p>At that moment, the platform needs two qualities:</p>
<ol>
<li><strong>Honest error handling</strong> (clear status, not vague mystery states)</li>
<li><strong>Clean recovery</strong> (retry without rebuilding the whole world)</li>
</ol>
<p>November’s work has been about exactly that: giving Qilin.Cloud pipelines a more mature operational posture through:</p>
<ul>
<li><strong>advanced error handling settings</strong></li>
<li><strong>manual retry for pipeline and processor executions</strong></li>
<li><strong>reproducibility safeguards (locking definitions while running)</strong></li>
</ul>
<p>This is where platform trust is earned.</p></div>
			</div>
			</div>
				
				
				
				
			</div><div class="et_pb_row et_pb_row_25">
				<div class="et_pb_column et_pb_column_4_4 et_pb_column_25  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_3">
				
				
				
				
				
				
				<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='#Theoldworlditfailedsowereruneverything' data-hl='2'></span><a href='#Theoldworlditfailedsowereruneverything' id='Theoldworlditfailedsowereruneverything_toc_headding'>The old world: “it failed, so we rerun everything”</a></div></li><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#ErrorhandlingthatmatchesrealityIgnoredvsWarningvsFailed' data-hl='2'></span><a href='#ErrorhandlingthatmatchesrealityIgnoredvsWarningvsFailed' id='ErrorhandlingthatmatchesrealityIgnoredvsWarningvsFailed_toc_headding'>Error handling that matches reality: Ignored vs Warning vs Failed</a></div></li><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#Manualretrywhentheproblemisfixedtheworkshouldntbelost' data-hl='2'></span><a href='#Manualretrywhentheproblemisfixedtheworkshouldntbelost' id='Manualretrywhentheproblemisfixedtheworkshouldntbelost_toc_headding'>Manual retry: when the problem is fixed, the work shouldn’t be lost</a></div></li><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#Whydefinitionlockingmatters' data-hl='2'></span><a href='#Whydefinitionlockingmatters' id='Whydefinitionlockingmatters_toc_headding'>Why definition locking matters</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='#Formerchantsandagencies' data-hl='2'></span><a href='#Formerchantsandagencies' id='Formerchantsandagencies_toc_headding'>For merchants and agencies</a></div></li><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#Forinvestors' data-hl='2'></span><a href='#Forinvestors' id='Forinvestors_toc_headding'>For investors</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='#Thegoalfailhonestlyrecovercleanly' data-hl='2'></span><a href='#Thegoalfailhonestlyrecovercleanly' id='Thegoalfailhonestlyrecovercleanly_toc_headding'>The goal: fail honestly, recover cleanly</a></div></li></ul></div>
            </div>
        </div>
        
				</div>
			</div>
			</div>
				
				
				
				
			</div><div class="et_pb_row et_pb_row_30">
				<div class="et_pb_column et_pb_column_4_4 et_pb_column_30  et_pb_css_mix_blend_mode_passthrough et-last-child">
				
				
				
				
				<div class="et_pb_module et_pb_blurb et_pb_blurb_55  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 old world: “it failed, so we rerun everything”</span></h2>
						<div class="et_pb_blurb_description"><p>Traditional integration recovery often looks like:</p>
<ul>
<li>re-run the whole job</li>
<li>hope duplicates don’t happen</li>
<li>manually reconcile partial updates</li>
<li>dig through logs to guess what happened</li>
</ul>
<p>It’s expensive, risky, and it doesn’t scale as you add more pipelines.</p>
<p>So Qilin.Cloud is moving toward a cleaner model:</p>
<p><em><strong>&gt; Treat executions as trackable artifacts you can inspect, classify, and retry.</strong></em></p></div>
					</div>
				</div>
			</div>
			</div>
				
				
				
				
			</div><div class="et_pb_row et_pb_row_31">
				<div class="et_pb_column et_pb_column_4_4 et_pb_column_31  et_pb_css_mix_blend_mode_passthrough et-last-child">
				
				
				
				
				<div class="et_pb_module et_pb_blurb et_pb_blurb_56  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>Error handling that matches reality: Ignored vs Warning vs Failed</span></h2>
						<div class="et_pb_blurb_description"><p>Not every error deserves the same response.</p>
<p>Sometimes:</p>
<ul>
<li>a product is missing a non-critical field → warn and continue</li>
<li>one optional enrichment service times out → warn and continue</li>
<li>the output connector rejects the object → fail the object (or the pipeline) depending on policy</li>
<li>a validation error occurs → stop, because continuing would produce bad data</li>
</ul>
<p>So processors can be configured with settings like:</p>
<ul>
<li><strong>continue on error</strong> (do we proceed downstream?)</li>
<li><strong>custom error status</strong> (how should this failure be classified?)</li>
</ul>
<p>This allows a pipeline to finish with nuance:</p>
<ul>
<li><strong>Completed</strong> (all good)</li>
<li><strong>Completed with warnings</strong> (action required, but business kept moving)</li>
<li><strong>Failed</strong> (hard stop)</li>
</ul>
<p>That is exactly how experienced operations teams think.</p></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_57  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>Manual retry: when the problem is fixed, the work shouldn’t be lost</span></h2>
						<div class="et_pb_blurb_description"><p>Sometimes failure isn’t caused by your data or your pipeline logic.</p>
<p>Sometimes it’s just the world:</p>
<ul>
<li>an external API is down</li>
<li>a token expired</li>
<li>a marketplace has a temporary outage</li>
<li>a partner system returns 500 for 20 minutes and then “recovers”</li>
</ul>
<p>In those cases, the right response is often:</p>
<p><strong>retry the execution once the dependency is healthy again.</strong></p>
<p>Qilin.Cloud now supports manual retry of:</p>
<ul>
<li>a <strong>pipeline execution</strong></li>
<li>a <strong>processor execution</strong></li>
</ul>
<p>based on execution identifiers from Data Flow Tracking.</p>
<p>This turns recovery into a controlled operation:</p>
<ul>
<li>inspect what failed</li>
<li>fix the root cause (credentials, upstream system, connectivity)</li>
<li>retry <em>only the relevant execution</em>, without replaying everything blindly</li>
</ul></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_accordion et_pb_accordion_7">
				
				
				
				
				<div class="et_pb_toggle et_pb_module et_pb_accordion_item et_pb_accordion_item_7  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_58  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 definition locking matters</span></h2>
						<div class="et_pb_blurb_description"><p>Retries are only trustworthy when they’re reproducible.</p>
<p>If a pipeline definition changes while an execution is running, you get an ugly question:</p>
<p><em><strong>&gt; “Which version actually ran?”</strong></em></p>
<p>So one of the operational safeguards is making pipeline definitions effectively <strong>stable during execution</strong>. That way, when you retry an execution, you’re retrying the same logic &#8211; unless you intentionally deploy a new version.</p>
<p>This is the kind of “boring correctness” that makes debugging and audits sane.</p></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_59  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"><ul>
<li>explicit error semantics reduce debugging time</li>
<li>retries become controlled operations, not guesswork</li>
<li>execution identity becomes a first-class tool (“retry execution X”)</li>
<li>fewer custom “recovery scripts” and manual reconciliations</li>
</ul></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_60  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 and agencies</span></h2>
						<div class="et_pb_blurb_description"><ul>
<li>faster incident recovery</li>
<li>fewer duplicate updates</li>
<li>better transparency into what happened and what was retried</li>
<li>easier operations handover (“here’s the execution ID and the status story”)</li>
</ul></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_61  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 investors</span></h2>
						<div class="et_pb_blurb_description"><p>Operational maturity is revenue maturity:</p>
<ul>
<li>fewer support escalations</li>
<li>higher trust from larger customers</li>
<li>more complex use cases become feasible</li>
<li>lower cost of operating at scale</li>
</ul></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_62  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>In December we’ll zoom into a very concrete connector milestone:</p>
<p><strong>Kaufland offer sync improvements &#8211; </strong>with a focus on update-only strategies that merchants can trust and agencies can implement cleanly.</p></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_63  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 goal: fail honestly, recover cleanly</span></h2>
						<div class="et_pb_blurb_description"><p>Failures will happen.</p>
<p>The platform’s job isn’t to pretend they won’t.</p>
<p>The platform’s job is to make failure:</p>
<ul>
<li>observable</li>
<li>classifiable</li>
<li>recoverable</li>
</ul>
<p>That’s the direction Qilin.Cloud is heading—so operations feel less like firefighting and more like engineering.</p></div>
					</div>
				</div>
			</div>
			</div>
				
				
				
				
			</div>
				
				
			</div>
<p>The post <a rel="nofollow" href="https://qilin.cloud/error-handling-manual-retry-recover-like-grown-up-platform/">Error Handling &amp; Manual Retry: Recovering from Failures Like a Grown-Up Platform</a> appeared first on <a rel="nofollow" href="https://qilin.cloud">Qilin.Cloud</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>The Claim Check Pattern: Moving Files Through Pipelines Without Melting Them</title>
		<link>https://qilin.cloud/claim-check-pattern-moving-files-without-melting-pipelines/</link>
		
		<dc:creator><![CDATA[Carina Müller]]></dc:creator>
		<pubDate>Fri, 31 Oct 2025 08:00:00 +0000</pubDate>
				<category><![CDATA[Product Updates]]></category>
		<category><![CDATA[binary]]></category>
		<category><![CDATA[claim check pattern]]></category>
		<category><![CDATA[files]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[pipelines]]></category>
		<guid isPermaLink="false">https://qilin.cloud/?p=3723</guid>

					<description><![CDATA[<p>October’s update: support for the Claim Check pattern in Qilin.Cloud pipelines. Store binary data once, pass blob references through the flow, and handle uploads without memory pain.</p>
<p>The post <a rel="nofollow" href="https://qilin.cloud/claim-check-pattern-moving-files-without-melting-pipelines/">The Claim Check Pattern: Moving Files Through Pipelines Without Melting Them</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_4 et_section_regular" >
				
				
				
				
				
				
				<div class="et_pb_row et_pb_row_32">
				<div class="et_pb_column et_pb_column_4_4 et_pb_column_32  et_pb_css_mix_blend_mode_passthrough et-last-child">
				
				
				
				
				<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"><p>There’s a reason airports don’t hand you your suitcase and say: “Please carry this through every checkpoint yourself.”</p>
<p>They give you a <strong>claim ticket</strong>.</p>
<p>That’s the essence of the <strong>Claim Check pattern</strong> &#8211; a classic enterprise integration trick that becomes increasingly important in modern commerce, where “data” isn’t just JSON anymore:</p>
<ul>
<li>product images</li>
<li>PDFs (manuals, invoices, labels)</li>
<li>CSV exports</li>
<li>media assets for marketplaces</li>
</ul>
<p>October’s work has been about making Qilin.Cloud pipelines handle binary data in a way that’s sane, scalable, and operationally friendly:</p>
<p><strong>Store the file once. Pass references through the pipeline.</strong></p></div>
			</div>
			</div>
				
				
				
				
			</div><div class="et_pb_row et_pb_row_33">
				<div class="et_pb_column et_pb_column_4_4 et_pb_column_33  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_4">
				
				
				
				
				
				
				<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='#Theproblemwithjustincludethebytes' data-hl='2'></span><a href='#Theproblemwithjustincludethebytes' id='Theproblemwithjustincludethebytes_toc_headding'>The problem with “just include the bytes”</a></div></li><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#BlobReferencesfilesasfirstclasscitizenswithoutthebytes' data-hl='2'></span><a href='#BlobReferencesfilesasfirstclasscitizenswithoutthebytes' id='BlobReferencesfilesasfirstclasscitizenswithoutthebytes_toc_headding'>Blob References: files as first-class citizens (without the bytes)</a></div></li><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#WheretheClaimCheckpatternshines' data-hl='2'></span><a href='#WheretheClaimCheckpatternshines' id='WheretheClaimCheckpatternshines_toc_headding'>Where the Claim Check pattern shines</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='#1Productimagepipelines' data-hl='3'></span><a href='#1Productimagepipelines' id='1Productimagepipelines_toc_headding'>1) Product image pipelines</a></div></li><li class="pac_dtoc_li_heading_level_3" role="treeitem" ><div role="presentation" ><span data-href='#2Invoicelabelworkflows' data-hl='3'></span><a href='#2Invoicelabelworkflows' id='2Invoicelabelworkflows_toc_headding'>2) Invoice / label workflows</a></div></li><li class="pac_dtoc_li_heading_level_3" role="treeitem" ><div role="presentation" ><span data-href='#3Bulkcatalogexports' data-hl='3'></span><a href='#3Bulkcatalogexports' id='3Bulkcatalogexports_toc_headding'>3) Bulk catalog exports</a></div></li></ul><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#HTTPRequestProcessormultipartuploadswithoutmemorypain' data-hl='2'></span><a href='#HTTPRequestProcessormultipartuploadswithoutmemorypain' id='HTTPRequestProcessormultipartuploadswithoutmemorypain_toc_headding'>HTTP Request Processor: multipart uploads without memory pain</a></div></li><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#Anoteforengineersthisisoldwisdomformodernpayloads' data-hl='2'></span><a href='#Anoteforengineersthisisoldwisdomformodernpayloads' id='Anoteforengineersthisisoldwisdomformodernpayloads_toc_headding'>A note for engineers: this is “old wisdom” for modern payloads</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='#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='#Dontcarrysuitcasesthroughthewholeairport' data-hl='2'></span><a href='#Dontcarrysuitcasesthroughthewholeairport' id='Dontcarrysuitcasesthroughthewholeairport_toc_headding'>Don’t carry suitcases through the whole airport</a></div></li></ul></div>
            </div>
        </div>
        
				</div>
			</div>
			</div>
				
				
				
				
			</div><div class="et_pb_row et_pb_row_38">
				<div class="et_pb_column et_pb_column_4_4 et_pb_column_38  et_pb_css_mix_blend_mode_passthrough et-last-child">
				
				
				
				
				<div class="et_pb_module et_pb_blurb et_pb_blurb_72  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 problem with “just include the bytes”</span></h2>
						<div class="et_pb_blurb_description"><p>If you try to push binary payloads through every pipeline step, a few things go wrong fast:</p>
<ul>
<li>memory spikes</li>
<li>request sizes explode</li>
<li>retries become expensive</li>
<li>logging and tracking become noisy (or impossible)</li>
<li>transformations become unsafe (“did we accidentally re-encode it?”)</li>
</ul>
<p>It’s the same lesson we learned years ago with large messages in messaging systems:</p>
<p><em><strong>&gt; Large payloads don’t belong in the pipe. They belong beside the pipe.</strong></em></p></div>
					</div>
				</div>
			</div>
			</div>
				
				
				
				
			</div><div class="et_pb_row et_pb_row_39">
				<div class="et_pb_column et_pb_column_4_4 et_pb_column_39  et_pb_css_mix_blend_mode_passthrough et-last-child">
				
				
				
				
				<div class="et_pb_module et_pb_blurb et_pb_blurb_73  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>Blob References: files as first-class citizens (without the bytes)</span></h2>
						<div class="et_pb_blurb_description"><p>In Qilin.Cloud, binary content can be represented as a <strong>BlobReference</strong> object.</p>
<p>Instead of carrying raw bytes, a pipeline can carry metadata like:</p>
<p>&#8211; blob name / container name<br />&#8211; public or internal URL<br />&#8211; content type<br />&#8211; size<br />&#8211; optional tags<br />&#8211; original filename</p>
<p>So a flow object might include something like:</p>
<pre>{
  "contentType": "image/jpeg",
  "fileName": "product_123.jpg",
  "size": 482193,
  "publicUrl": "https://…/product_123.jpg",
  "containerName": "assets"
}
</pre>
<p>Now every step downstream can refer to “the file” without transporting it.</p>
<p>That makes retries cheap, tracking clear, and throughput predictable.</p></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_74  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>Where the Claim Check pattern shines</span></h2>
						<div class="et_pb_blurb_description"><h3>1) Product image pipelines</h3>
<ul>
<li>ingest images from a DAM or PIM</li>
<li>store once</li>
<li>publish to multiple destinations (Shopware, marketplaces, feeds)</li>
</ul>
<h3>2) Invoice / label workflows</h3>
<ul>
<li>generate PDFs</li>
<li>store references</li>
<li>send links or forward to systems that fetch on demand</li>
</ul>
<h3>3) Bulk catalog exports</h3>
<ul>
<li>assemble big files</li>
<li>store as blobs</li>
<li>send references to partners instead of pushing megabytes through APIs repeatedly</li>
</ul></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_75  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>HTTP Request Processor: multipart uploads without memory pain</span></h2>
						<div class="et_pb_blurb_description"><p>The HTTP Request Processor can handle multipart form uploads where the “file” is sourced from a URL (for example, a blob public URL).</p>
<p>That means you can build flows like:</p>
<ol>
<li>receive an image URL from a webhook</li>
<li>store it as a blob (or reference it)</li>
<li>upload it to a destination API via multipart</li>
<li>continue processing with tracking intact</li>
</ol>
<p>The pipeline stays stream-friendly and predictable.</p></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_accordion et_pb_accordion_9">
				
				
				
				
				<div class="et_pb_toggle et_pb_module et_pb_accordion_item et_pb_accordion_item_9  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_76  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>A note for engineers: this is “old wisdom” for modern payloads</span></h2>
						<div class="et_pb_blurb_description"><p>Claim Check isn’t a new invention.</p>
<p>It’s one of those patterns seasoned integration engineers used long before “cloud native” became a phrase.</p>
<p>What’s new is that modern commerce workflows need it constantly &#8211; because media, documents, and binaries are now part of everyday commerce data.</p>
<p>Qilin.Cloud is making the pattern pipeline-native.</p></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_77  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> fewer failures when syncing images or documents; better reliability for catalog publishing.</li>
<li><strong>Agencies:</strong> cleaner implementations (no custom file-handling services), easier scaling across clients.</li>
<li><strong>Investors:</strong> binary handling is a capability multiplier—more workflows, bigger customers, less operational strain.</li>
</ul></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_78  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>In November, we’ll zoom into the moment every integration fears:</p>
<p><strong>something failed. Now what?</strong></p>
<p>We’ll cover improvements around error handling, reproducibility, and manual retries—so operations teams can recover cleanly without rebuilding history from scratch.</p></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_79  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>Don’t carry suitcases through the whole airport</span></h2>
						<div class="et_pb_blurb_description"><p>Carry a claim ticket.</p>
<p>That’s what Qilin.Cloud is bringing to binary data workflows: clean references, clean tracking, and pipelines that don’t melt under file payloads.</p></div>
					</div>
				</div>
			</div>
			</div>
				
				
				
				
			</div>
				
				
			</div>
<p>The post <a rel="nofollow" href="https://qilin.cloud/claim-check-pattern-moving-files-without-melting-pipelines/">The Claim Check Pattern: Moving Files Through Pipelines Without Melting Them</a> appeared first on <a rel="nofollow" href="https://qilin.cloud">Qilin.Cloud</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Time Entry &#038; Email: Scheduling and Notifications Built into Your Pipelines</title>
		<link>https://qilin.cloud/time-entry-email-scheduling-notifications-pipelines/</link>
		
		<dc:creator><![CDATA[Levent Yaman]]></dc:creator>
		<pubDate>Tue, 30 Sep 2025 08:00:00 +0000</pubDate>
				<category><![CDATA[Product Updates]]></category>
		<category><![CDATA[email]]></category>
		<category><![CDATA[notifications]]></category>
		<category><![CDATA[pipelines]]></category>
		<category><![CDATA[scheduling]]></category>
		<category><![CDATA[time entry]]></category>
		<guid isPermaLink="false">https://qilin.cloud/?p=3716</guid>

					<description><![CDATA[<p>September’s update adds Time Entry scheduling and Email notifications to Qilin.Cloud pipelines—classic operational rhythms, now observable and configurable as first-class processors.</p>
<p>The post <a rel="nofollow" href="https://qilin.cloud/time-entry-email-scheduling-notifications-pipelines/">Time Entry &amp; Email: Scheduling and Notifications Built into Your Pipelines</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_5 et_section_regular" >
				
				
				
				
				
				
				<div class="et_pb_row et_pb_row_40">
				<div class="et_pb_column et_pb_column_4_4 et_pb_column_40  et_pb_css_mix_blend_mode_passthrough et-last-child">
				
				
				
				
				<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>The oldest automation tool in the world is… time.</p>
<p>Before servers, before cron, before CI/CD, we had:</p>
<ul>
<li>“do this every day”</li>
<li>“run this every 15 minutes”</li>
<li>“send a report on Monday morning”</li>
<li>“wake me up if something breaks”</li>
</ul>
<p>Commerce operations still run on those rhythms.</p>
<p>So September’s update brings two classic, practical primitives directly into Qilin.Cloud pipelines:</p>
<ul>
<li><strong>Time Entry Processor</strong> &#8211; trigger flows on schedules (intervals or cron)</li>
<li><strong>Email Processor</strong> &#8211; send notifications (dynamic, templated, permissioned)</li>
</ul>
<p>This is the “boring” stuff that makes systems usable in production.</p></div>
			</div>
			</div>
				
				
				
				
			</div><div class="et_pb_row et_pb_row_41">
				<div class="et_pb_column et_pb_column_4_4 et_pb_column_41  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_5">
				
				
				
				
				
				
				<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='#TimeEntryProcessorcronjobsbutpipelinenative' data-hl='2'></span><a href='#TimeEntryProcessorcronjobsbutpipelinenative' id='TimeEntryProcessorcronjobsbutpipelinenative_toc_headding'>Time Entry Processor: cron jobs, but pipeline-native</a></div></li><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#Apracticalscheduleexamplecron' data-hl='2'></span><a href='#Apracticalscheduleexamplecron' id='Apracticalscheduleexamplecron_toc_headding'>A practical schedule example (cron)</a></div></li><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#EmailProcessornotificationswithoutcustomservices' data-hl='2'></span><a href='#EmailProcessornotificationswithoutcustomservices' id='EmailProcessornotificationswithoutcustomservices_toc_headding'>Email Processor: notifications without custom services</a></div></li><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#Examplesendanalertwhensomethingfails' data-hl='2'></span><a href='#Examplesendanalertwhensomethingfails' id='Examplesendanalertwhensomethingfails_toc_headding'>Example: send an alert when something fails</a></div></li><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#Whyschedulenotificationsbelongtogether' data-hl='2'></span><a href='#Whyschedulenotificationsbelongtogether' id='Whyschedulenotificationsbelongtogether_toc_headding'>Why schedule + notifications belong together</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='#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='#AutomationisntmagicItsrhythm' data-hl='2'></span><a href='#AutomationisntmagicItsrhythm' id='AutomationisntmagicItsrhythm_toc_headding'>Automation isn’t magic. It’s rhythm.</a></div></li></ul></div>
            </div>
        </div>
        
				</div>
			</div>
			</div>
				
				
				
				
			</div><div class="et_pb_row et_pb_row_46">
				<div class="et_pb_column et_pb_column_4_4 et_pb_column_46  et_pb_css_mix_blend_mode_passthrough et-last-child">
				
				
				
				
				<div class="et_pb_module et_pb_blurb et_pb_blurb_89  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>Time Entry Processor: cron jobs, but pipeline-native</span></h2>
						<div class="et_pb_blurb_description"><p>Time Entry is an entry processor that starts a pipeline based on time.</p>
<p>It supports common scheduling styles:</p>
<ul>
<li><strong>simple intervals</strong> (e.g., every 15 minutes)</li>
<li><strong>cron expressions</strong> (e.g., “every weekday at 08:00”)</li>
<li><strong>time zones</strong> (because commerce does not run on UTC feelings)</li>
</ul>
<p>If you’ve been building scheduled integrations for years, you already know why this matters:</p>
<ul>
<li>fewer external schedulers</li>
<li>fewer scattered jobs across servers</li>
<li>schedules live with the pipeline definition</li>
<li>everything is trackable and observable in one place</li>
</ul></div>
					</div>
				</div>
			</div>
			</div>
				
				
				
				
			</div><div class="et_pb_row et_pb_row_47">
				<div class="et_pb_column et_pb_column_4_4 et_pb_column_47  et_pb_css_mix_blend_mode_passthrough et-last-child">
				
				
				
				
				<div class="et_pb_module et_pb_blurb et_pb_blurb_90  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>A practical schedule example (cron)</span></h2>
						<div class="et_pb_blurb_description"><pre>{
  "id": "time_entry",
  "type": "Qilin.TimeEntry",
  "config": {
    "scheduleType": "Cronjob",
    "cronExpression": "0 */15 * ? * *",
    "timeZone": "Europe/Berlin"
  }
}
</pre>
<p>That’s “every 15 minutes” in a predictable time zone.</p>
<p>No separate infrastructure. No mystery scheduler running on an old VM “because it always worked”.</p></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_91  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>Email Processor: notifications without custom services</span></h2>
						<div class="et_pb_blurb_description"><p>The Email Processor does what it says:</p>
<ul>
<li>sends email to one or more recipients</li>
<li>supports To / CC / BCC</li>
<li>allows dynamic values from pipeline execution context</li>
<li>supports templates via Scriban (so emails can be personalized and structured)</li>
<li>uses stored credentials (so you don’t paste SMTP passwords into configs)</li>
</ul>
<p>This becomes useful immediately for:</p>
<ul>
<li>failure alerts</li>
<li>daily/weekly summaries</li>
<li>“import finished” notifications</li>
<li>“data quality issue detected” reports</li>
<li>agency handover and operational transparency</li>
</ul></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_92  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>Example: send an alert when something fails</span></h2>
						<div class="et_pb_blurb_description"><p>A simplified config:</p>
<pre>{
  "EmailProviderName": "CustomSmtpProvider",
  "credentialId": "credential-guid",
  "Receivers": { "raw": ["<span 
                data-original-string='NHwEFa8LrkRFstUb7Dzkaw==4aapR/QRBr6EY0/pbyNHhvMzcg+P6MQ2M2Uo869WquTtlE='
                class='apbct-email-encoder'
                title='This contact has been encoded by Anti-Spam by CleanTalk. Click to decode. To finish the decoding make sure that JavaScript is enabled in your browser.'>op<span class="apbct-blur">*</span>@<span class="apbct-blur">*********</span>ny.com</span>"] },
  "From": { "raw": "<span 
                data-original-string='FtLISTNQ7UTx+OxUwbanRg==4aal3xpbxf81FCT3mIWutXo0pOi0Ib2WKEsaE86ufRkhcE='
                class='apbct-email-encoder'
                title='This contact has been encoded by Anti-Spam by CleanTalk. Click to decode. To finish the decoding make sure that JavaScript is enabled in your browser.'>qi<span class="apbct-blur">**********</span>@<span class="apbct-blur">*********</span>ny.com</span>" },
  "Subject": "Qilin pipeline alert",
  "BodyContent": "Pipeline {{ FlowObjectAttributes.entry.pipelineId }} reported {{ FlowObjectAttributes.entry.status }}",
  "IsBodyHtml": false
}
</pre>
<p>You can also use templating to include richer context:</p>
<ul>
<li>object IDs</li>
<li>execution IDs</li>
<li>counts (how many items processed / failed)</li>
<li>links to tracking pages</li>
</ul></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_accordion et_pb_accordion_11">
				
				
				
				
				<div class="et_pb_toggle et_pb_module et_pb_accordion_item et_pb_accordion_item_11  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_93  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 schedule + notifications belong together</span></h2>
						<div class="et_pb_blurb_description"><p>A scheduled pipeline without notifications is a silent machine.</p>
<p>A notification system without scheduling becomes reactive chaos.</p>
<p>Together, they enable a very traditional &#8211; but very effective &#8211; operational pattern:</p>
<ol>
<li>run predictable jobs on predictable rhythms</li>
<li>surface exceptions immediately</li>
<li>let humans focus on decisions, not polling dashboards</li>
</ol></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_94  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"><ul>
<li>scheduling lives with the pipeline definition</li>
<li>templates are versionable, testable, and dynamic</li>
<li>credentials are managed centrally and permissioned</li>
<li>fewer “sidecar services” just to send emails or run cron</li>
</ul></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_95  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> get operational transparency without extra tooling</li>
<li><strong>Agencies:</strong> deliver “managed integrations” with built-in reporting and alerts</li>
<li><strong>Investors:</strong> these are features that reduce support cost and increase platform stickiness</li>
</ul></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_96  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>In October we’ll tackle a very modern problem with a very classic pattern:</p>
<p><strong>moving large binary data through pipelines without moving it through pipelines.</strong></p>
<p>(Yes, that sentence is weird. It will make sense.)</p></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_97  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>Automation isn’t magic. It’s rhythm.</span></h2>
						<div class="et_pb_blurb_description"><p>Some of the best engineering work is turning “how we always did it” into platform primitives.</p>
<p>Time Entry and Email are exactly that: practical tools for real operations, baked into Qilin.Cloud.</p></div>
					</div>
				</div>
			</div>
			</div>
				
				
				
				
			</div>
				
				
			</div>
<p>The post <a rel="nofollow" href="https://qilin.cloud/time-entry-email-scheduling-notifications-pipelines/">Time Entry &amp; Email: Scheduling and Notifications Built into Your Pipelines</a> appeared first on <a rel="nofollow" href="https://qilin.cloud">Qilin.Cloud</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Batch Output + Switch-Case: Shipping Pallets and Making Smart Routing Decisions</title>
		<link>https://qilin.cloud/batch-output-switch-case-smart-routing/</link>
		
		<dc:creator><![CDATA[Tho Duong]]></dc:creator>
		<pubDate>Sun, 31 Aug 2025 08:00:00 +0000</pubDate>
				<category><![CDATA[Product Updates]]></category>
		<category><![CDATA[automation]]></category>
		<category><![CDATA[batch output]]></category>
		<category><![CDATA[pipelines]]></category>
		<category><![CDATA[routing]]></category>
		<category><![CDATA[switch-case]]></category>
		<guid isPermaLink="false">https://qilin.cloud/?p=3709</guid>

					<description><![CDATA[<p>August’s update: Batch Output Connector for efficient bulk delivery and Switch-Case routing with multi-conditions—so pipelines can scale in volume and intelligence without turning into code spaghetti.</p>
<p>The post <a rel="nofollow" href="https://qilin.cloud/batch-output-switch-case-smart-routing/">Batch Output + Switch-Case: Shipping Pallets and Making Smart Routing Decisions</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_6 et_section_regular" >
				
				
				
				
				
				
				<div class="et_pb_row et_pb_row_48">
				<div class="et_pb_column et_pb_column_4_4 et_pb_column_48  et_pb_css_mix_blend_mode_passthrough et-last-child">
				
				
				
				
				<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"><p>Batches are great.</p>
<p>But once you start batching, you immediately meet two new questions:</p>
<ol>
<li><strong>How do we ship the batch efficiently to a connector?</strong></li>
<li><strong>How do we route different items (or batches) differently without writing custom code?</strong></li>
</ol>
<p>August’s work tackles both with two powerful building blocks:</p>
<ul>
<li><strong>Batch Output Connector Processor</strong></li>
<li><strong>Switch-Case Processor (multi-conditions)</strong></li>
</ul>
<p>This is where pipelines start feeling less like “ETL flows” and more like programmable integration systems &#8211; without becoming an unmaintainable codebase.</p></div>
			</div>
			</div>
				
				
				
				
			</div><div class="et_pb_row et_pb_row_49">
				<div class="et_pb_column et_pb_column_4_4 et_pb_column_49  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_6">
				
				
				
				
				
				
				<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='#BatchOutputConnectorshippingpalletsnotsingleparcels' data-hl='2'></span><a href='#BatchOutputConnectorshippingpalletsnotsingleparcels' id='BatchOutputConnectorshippingpalletsnotsingleparcels_toc_headding'>Batch Output Connector: shipping pallets, not single parcels</a></div></li><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#SwitchCaseProcessorroutinglogicthatscales' data-hl='2'></span><a href='#SwitchCaseProcessorroutinglogicthatscales' id='SwitchCaseProcessorroutinglogicthatscales_toc_headding'>Switch-Case Processor: routing logic that scales</a></div></li><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#Whymulticonditionsmatter' data-hl='2'></span><a href='#Whymulticonditionsmatter' id='Whymulticonditionsmatter_toc_headding'>Why multi-conditions matter</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='#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='#Commercerunsondecisionsanddecisionsrunondata' data-hl='2'></span><a href='#Commercerunsondecisionsanddecisionsrunondata' id='Commercerunsondecisionsanddecisionsrunondata_toc_headding'>Commerce runs on decisions (and decisions run on data)</a></div></li></ul></div>
            </div>
        </div>
        
				</div>
			</div>
			</div>
				
				
				
				
			</div><div class="et_pb_row et_pb_row_54">
				<div class="et_pb_column et_pb_column_4_4 et_pb_column_54  et_pb_css_mix_blend_mode_passthrough et-last-child">
				
				
				
				
				<div class="et_pb_module et_pb_blurb et_pb_blurb_105  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>Batch Output Connector: shipping pallets, not single parcels</span></h2>
						<div class="et_pb_blurb_description"><p>If QQS + Buffer Entry is the “warehouse staging area”, the Batch Output Connector is the “truck”.</p>
<p>Instead of calling a connector once per object, it can:</p>
<ul>
<li>take a list of objects</li>
<li>package them into a connector request</li>
<li>send them in one call</li>
<li>handle a response that contains success/error per item</li>
</ul>
<p>A typical config looks like:</p>
<pre>{
  "id": "batch_out",
  "type": "Qilin.BatchOutputConnector",
  "config": {
    "outputConnectorId": "connector-guid",
    "domainName": "Offer",
    "objectTypePath": "$.FlowObjectContents.entry.objectType",
    "objectIdsPath": "$.FlowObjectContents.entry.objectIds",
    "objectBodiesPath": "$.FlowObjectContents.entry.objectData"
  }
}
</pre>
<p>When paired with buffering, this gives you classic enterprise integration behavior:</p>
<ul>
<li>fewer HTTP calls</li>
<li>better throughput control</li>
<li>reduced connector overhead</li>
<li>easier handling of platform quotas and rate limits</li>
</ul></div>
					</div>
				</div>
			</div>
			</div>
				
				
				
				
			</div><div class="et_pb_row et_pb_row_55">
				<div class="et_pb_column et_pb_column_4_4 et_pb_column_55  et_pb_css_mix_blend_mode_passthrough et-last-child">
				
				
				
				
				<div class="et_pb_module et_pb_blurb et_pb_blurb_106  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>Switch-Case Processor: routing logic that scales</span></h2>
						<div class="et_pb_blurb_description"><p>The next problem: not every object should go to the same place.</p>
<p>You might need to route by:</p>
<ul>
<li>marketplace</li>
<li>storefront</li>
<li>country</li>
<li>product category</li>
<li>pricing strategy</li>
<li>stock availability</li>
<li>compliance rules</li>
</ul>
<p>In the old world, routing becomes a pile of nested if-statements.</p>
<p>In Qilin, the Switch-Case Processor gives you a structured approach:</p>
<ul>
<li>each outgoing connection can define a condition (Filter Predicate)</li>
<li>Qilin activates the first matching case</li>
<li>a default route can catch everything else</li>
</ul>
<p>A simplified mental model:</p>
<ul>
<li>if case A matches → follow path A</li>
<li>else if case B matches → follow path B</li>
<li>else → follow default</li>
</ul>
<p>This is the “switch statement” you already know &#8211; adapted to pipeline routing.</p></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_107  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 multi-conditions matter</span></h2>
						<div class="et_pb_blurb_description"><p>Multi-conditions are the difference between:</p>
<ul>
<li>“we can build a demo”</li>
<li>and “we can build policies”</li>
</ul>
<p>Because real routing often looks like:</p>
<ul>
<li>If it’s a hazardous material AND destination is EU → route to compliance enrichment</li>
<li>If it’s a luxury brand AND price is missing → stop and alert</li>
<li>If it’s marketplace X AND stock &lt; 5 → route to low-stock strategy</li>
</ul>
<p>Switch-case lets you express this cleanly, reuse it, and review it.</p></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_108  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"><ul>
<li>batching reduces connector chatter and failure surfaces</li>
<li>switch-case reduces custom code and makes routing auditable</li>
<li>both are pipeline-native, meaning you get tracking, logs, and consistent error behavior</li>
</ul></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_109  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> faster, more stable syncs—especially for high-volume catalog/offer updates</li>
<li><strong>Agencies:</strong> cleaner architectures and reusable routing templates across clients</li>
<li><strong>Investors:</strong> this is platform maturity that increases addressable use cases and lowers delivery cost</li>
</ul></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_110  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>In September, we’ll shift from routing and batching into a different kind of control:</p>
<p><strong>time.</strong></p>
<p>Scheduling is a core part of integration work, and Qilin is adding pipeline primitives for time-based triggering and notifications.</p></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_111  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>Commerce runs on decisions (and decisions run on data)</span></h2>
						<div class="et_pb_blurb_description"><p>Batches make shipping efficient.</p>
<p>Switch-case makes shipping intelligent.</p>
<p>Qilin.Cloud is building both—so your integrations can grow in volume and complexity without growing in chaos.</p></div>
					</div>
				</div>
			</div>
			</div>
				
				
				
				
			</div>
				
				
			</div>
<p>The post <a rel="nofollow" href="https://qilin.cloud/batch-output-switch-case-smart-routing/">Batch Output + Switch-Case: Shipping Pallets and Making Smart Routing Decisions</a> appeared first on <a rel="nofollow" href="https://qilin.cloud">Qilin.Cloud</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Queue Storage &#038; Buffering: When Real-Time Isn’t the Whole Story</title>
		<link>https://qilin.cloud/queue-storage-buffering-when-real-time-isnt-everything/</link>
		
		<dc:creator><![CDATA[Thien Trinh Duc]]></dc:creator>
		<pubDate>Thu, 31 Jul 2025 08:00:00 +0000</pubDate>
				<category><![CDATA[Product Updates]]></category>
		<category><![CDATA[batching]]></category>
		<category><![CDATA[buffering]]></category>
		<category><![CDATA[cost control]]></category>
		<category><![CDATA[queue]]></category>
		<category><![CDATA[scheduling]]></category>
		<guid isPermaLink="false">https://qilin.cloud/?p=3700</guid>

					<description><![CDATA[<p>July’s update: Qilin Queue Storage + buffering processors. Collect objects, trigger batches by size or schedule, and ship data in stable chunks that respect connector limits.</p>
<p>The post <a rel="nofollow" href="https://qilin.cloud/queue-storage-buffering-when-real-time-isnt-everything/">Queue Storage &amp; Buffering: When Real-Time Isn’t the Whole Story</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_7 et_section_regular" >
				
				
				
				
				
				
				<div class="et_pb_row et_pb_row_56">
				<div class="et_pb_column et_pb_column_4_4 et_pb_column_56  et_pb_css_mix_blend_mode_passthrough et-last-child">
				
				
				
				
				<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>The oldest trick in commerce operations is also one of the smartest:</p>
<p><strong>Don’t ship boxes one by one when you can ship a pallet.</strong></p>
<p>Real-time is great &#8211; when you need it.</p>
<p>But experienced teams know that many workflows are better when they run in controlled batches:</p>
<ul>
<li>catalog sync overnight</li>
<li>stock updates every 15 minutes</li>
<li>offer updates grouped to reduce API overhead</li>
<li>partner exports once per hour</li>
</ul>
<p>July’s development work has been about making this “batch wisdom” a first-class citizen in Qilin.Cloud via:</p>
<ul>
<li><strong>Qilin Queue Storage (QQS)</strong></li>
<li><strong>Push-to-Queue + Buffer Entry processors</strong></li>
<li><strong>Scheduling that respects real-world limits</strong></li>
</ul></div>
			</div>
			</div>
				
				
				
				
			</div><div class="et_pb_row et_pb_row_57">
				<div class="et_pb_column et_pb_column_4_4 et_pb_column_57  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_7">
				
				
				
				
				
				
				<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='#QilinQueueStorageastagingareaforpipelineoutputs' data-hl='2'></span><a href='#QilinQueueStorageastagingareaforpipelineoutputs' id='QilinQueueStorageastagingareaforpipelineoutputs_toc_headding'>Qilin Queue Storage: a staging area for pipeline outputs</a></div></li><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#Thedatamodelsimpleonpurpose' data-hl='2'></span><a href='#Thedatamodelsimpleonpurpose' id='Thedatamodelsimpleonpurpose_toc_headding'>The data model (simple, on purpose)</a></div></li><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#PushQilinObjectToQueueStorageProcessorcollectingitems' data-hl='2'></span><a href='#PushQilinObjectToQueueStorageProcessorcollectingitems' id='PushQilinObjectToQueueStorageProcessorcollectingitems_toc_headding'>PushQilinObjectToQueueStorage Processor: collecting items</a></div></li><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#BufferEntryProcessortriggeringthebatch' data-hl='2'></span><a href='#BufferEntryProcessortriggeringthebatch' id='BufferEntryProcessortriggeringthebatch_toc_headding'>Buffer Entry Processor: triggering the batch</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='#1ThresholdbasedRunwhenthequeuecontainsatleastNitems' data-hl='3'></span><a href='#1ThresholdbasedRunwhenthequeuecontainsatleastNitems' id='1ThresholdbasedRunwhenthequeuecontainsatleastNitems_toc_headding'>1) Threshold-basedRun when the queue contains at least N items:</a></div></li><li class="pac_dtoc_li_heading_level_3" role="treeitem" ><div role="presentation" ><span data-href='#2Schedulebased' data-hl='3'></span><a href='#2Schedulebased' id='2Schedulebased_toc_headding'>2) Schedule-based</a></div></li></ul><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#Whybatchingisaplatformfeaturenotjustanoptimization' data-hl='2'></span><a href='#Whybatchingisaplatformfeaturenotjustanoptimization' id='Whybatchingisaplatformfeaturenotjustanoptimization_toc_headding'>Why batching is a platform feature (not just an optimization)</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='#Arealisticexampleofferupdateswithoutratelimitpain' data-hl='2'></span><a href='#Arealisticexampleofferupdateswithoutratelimitpain' id='Arealisticexampleofferupdateswithoutratelimitpain_toc_headding'>A realistic example: offer updates without rate-limit pain</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='#Respecttheoldwisdombatchwhenitmakessense' data-hl='2'></span><a href='#Respecttheoldwisdombatchwhenitmakessense' id='Respecttheoldwisdombatchwhenitmakessense_toc_headding'>Respect the old wisdom: batch when it makes sense</a></div></li></ul></div>
            </div>
        </div>
        
				</div>
			</div>
			</div>
				
				
				
				
			</div><div class="et_pb_row et_pb_row_62">
				<div class="et_pb_column et_pb_column_4_4 et_pb_column_62  et_pb_css_mix_blend_mode_passthrough et-last-child">
				
				
				
				
				<div class="et_pb_module et_pb_blurb et_pb_blurb_120  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>Qilin Queue Storage: a staging area for pipeline outputs</span></h2>
						<div class="et_pb_blurb_description"><p>Think of QQS as a <strong>staging warehouse</strong> inside the platform.</p>
<p>Instead of pushing every object immediately to the next step, you can:</p>
<ol>
<li>collect objects into a queue storage</li>
<li>wait until the queue reaches a condition (size or time)</li>
<li>trigger a downstream pipeline step with a batch</li>
</ol>
<p>This is especially useful when destinations prefer bulk updates &#8211; or punish you with rate limits for chattiness.</p></div>
					</div>
				</div>
			</div>
			</div>
				
				
				
				
			</div><div class="et_pb_row et_pb_row_63">
				<div class="et_pb_column et_pb_column_4_4 et_pb_column_63  et_pb_css_mix_blend_mode_passthrough et-last-child">
				
				
				
				
				<div class="et_pb_module et_pb_blurb et_pb_blurb_121  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 data model (simple, on purpose)</span></h2>
						<div class="et_pb_blurb_description"><p>At the conceptual level:</p>
<ul>
<li>a <strong>Queue Storage</strong> belongs to a subscription and has a configured duration (how long items live)</li>
<li>a <strong>Queue Item</strong> stores:
<ul>
<li>object type</li>
<li>object ID</li>
<li>object data (serialized)</li>
<li>created timestamp</li>
<li>expiration timestamp</li>
</ul>
</li>
</ul>
<p>This gives you the platform equivalent of “put it in the staging area, and process it later”.</p></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_122  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>PushQilinObjectToQueueStorage Processor: collecting items</span></h2>
						<div class="et_pb_blurb_description"><p>This processor takes the current object in your flow and pushes it into a chosen queue storage.</p>
<p>Example:</p>
<pre>{
  "id": "push_to_queue",
  "type": "Qilin.PushQilinObjectToQueueStorage",
  "config": {
    "queueStorageId": "your-queue-storage-id",
    "objectType": "Offer",
    "domainName": "Offer",
    "domainObjectIdPath": "$.FlowObjectAttributes.entry.objectId"
  }
}
</pre>
<p>You can override the object ID or object type if needed, and you can write different object kinds to different queue storages.</p></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_123  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>Buffer Entry Processor: triggering the batch</span></h2>
						<div class="et_pb_blurb_description"><p>Once objects are in the queue, you need a clean way to “release” them downstream.</p>
<p>That’s what Buffer Entry does.</p>
<p>Two common trigger patterns:</p>
<h3>1) Threshold-based<br />Run when the queue contains at least N items:</h3>
<pre>{
  "id": "buffer_entry",
  "type": "Qilin.BufferEntry",
    "config": {
    "queueStorageId": "your-queue-storage-id",
    "minimumItemsToRelease": 150
  }
}
</pre>
<h3>2) Schedule-based</h3>
<p>Run on a schedule (cron expression), releasing what’s available.</p>
<p>This matches classic operational workflows: “every 15 minutes, push what changed.”</p></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_accordion et_pb_accordion_13">
				
				
				
				
				<div class="et_pb_toggle et_pb_module et_pb_accordion_item et_pb_accordion_item_13  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_124  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 batching is a platform feature (not just an optimization)</span></h2>
						<div class="et_pb_blurb_description"><h3>For developers</h3>
<ul>
<li>fewer connector calls, less overhead</li>
<li>easier throughput control with predictable bursts</li>
<li>reduced retry complexity (retries happen per batch, not per object)</li>
<li>clean separation between “capture changes” and “ship changes”</li>
</ul>
<h3>For merchants and agencies</h3>
<ul>
<li>stable sync behavior under load</li>
<li>predictable operational windows (e.g., nightly exports)</li>
<li>fewer “API limit exceeded” incidents</li>
<li>easier to align platform behavior with business rhythms</li>
</ul>
<h3>For investors</h3>
<p>Queue storage unlocks higher-volume use cases without linear increases in operational cost. That’s leverage.</p></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_125  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>A realistic example: offer updates without rate-limit pain</span></h2>
						<div class="et_pb_blurb_description"><p>Offers (price, stock, handling time) can change frequently.</p>
<p>Instead of pushing every micro-change instantly:</p>
<ul>
<li>collect offer updates in QQS</li>
<li>release them in batches every 10–15 minutes</li>
<li>ship a predictable batch to the connector</li>
</ul>
<p>This keeps data fresh enough for commerce… without turning your connector into a chatty stress test.</p></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_126  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>Once you can batch, the next step is:</p>
<p><strong>smarter branching and routing</strong>.</p>
<p>August will introduce more around conditional execution and switch-case routing &#8211; so pipelines can decide what to do with a batch based on content, not just schedule.</p></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_127  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>Respect the old wisdom: batch when it makes sense</span></h2>
						<div class="et_pb_blurb_description"><p>Real-time is exciting.</p>
<p>Batching is profitable.</p>
<p>Qilin.Cloud is building both &#8211; so you can choose the right tool for each workflow, instead of forcing everything into one tempo.</p></div>
					</div>
				</div>
			</div>
			</div>
				
				
				
				
			</div>
				
				
			</div>
<p>The post <a rel="nofollow" href="https://qilin.cloud/queue-storage-buffering-when-real-time-isnt-everything/">Queue Storage &amp; Buffering: When Real-Time Isn’t the Whole Story</a> appeared first on <a rel="nofollow" href="https://qilin.cloud">Qilin.Cloud</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Merge, Timeouts, Retries: Reliability Patterns for Composable Pipelines</title>
		<link>https://qilin.cloud/merge-timeouts-retries-reliability-patterns/</link>
		
		<dc:creator><![CDATA[Tuyen Nguyen]]></dc:creator>
		<pubDate>Mon, 30 Jun 2025 08:00:00 +0000</pubDate>
				<category><![CDATA[Product Updates]]></category>
		<category><![CDATA[error handling]]></category>
		<category><![CDATA[merge]]></category>
		<category><![CDATA[reliability]]></category>
		<category><![CDATA[retries]]></category>
		<category><![CDATA[timeouts]]></category>
		<guid isPermaLink="false">https://qilin.cloud/?p=3688</guid>

					<description><![CDATA[<p>June’s focus: making resilience explicit. Merge policies (all/any/required), structured timeouts, retries, and continue/stop behavior—so pipelines degrade gracefully instead of collapsing.</p>
<p>The post <a rel="nofollow" href="https://qilin.cloud/merge-timeouts-retries-reliability-patterns/">Merge, Timeouts, Retries: Reliability Patterns for Composable Pipelines</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_8 et_section_regular" >
				
				
				
				
				
				
				<div class="et_pb_row et_pb_row_64">
				<div class="et_pb_column et_pb_column_4_4 et_pb_column_64  et_pb_css_mix_blend_mode_passthrough et-last-child">
				
				
				
				
				<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"><p>Building a pipeline is easy.</p>
<p>Building a pipeline that behaves sensibly when the real world misbehaves… that’s where the craft lives.</p>
<p>External APIs time out. <br />One branch finishes fast, another crawls. <br />A connector returns a 500 for 3 minutes and then pretends nothing happened.</p>
<p>If you’ve lived through this, you know the traditional solutions:</p>
<ul>
<li>“just retry”</li>
<li>“just add a timeout”</li>
<li>“just wait for the other branch”</li>
<li>“just make it idempotent”</li>
</ul>
<p>All true, all vague.</p>
<p>June’s focus has been making those survival instincts <strong>explicit configuration</strong> inside Qilin.Cloud &#8211; especially around <strong>merging branches</strong> and handling errors without turning your pipeline into a fragile Jenga tower.</p></div>
			</div>
			</div>
				
				
				
				
			</div><div class="et_pb_row et_pb_row_65">
				<div class="et_pb_column et_pb_column_4_4 et_pb_column_65  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_8">
				
				
				
				
				
				
				<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='#MergeProcessorwhereparallelismmeetsreality' data-hl='2'></span><a href='#MergeProcessorwhereparallelismmeetsreality' id='MergeProcessorwhereparallelismmeetsreality_toc_headding'>Merge Processor: where parallelism meets reality</a></div></li><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#Threemergetimeoutpolicieschooseyourphilosophy' data-hl='2'></span><a href='#Threemergetimeoutpolicieschooseyourphilosophy' id='Threemergetimeoutpolicieschooseyourphilosophy_toc_headding'>Three merge timeout policies (choose your philosophy)</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='#1Waitforallinputprocessorsdefault' data-hl='3'></span><a href='#1Waitforallinputprocessorsdefault' id='1Waitforallinputprocessorsdefault_toc_headding'>1) Wait for all input processors (default)</a></div></li><li class="pac_dtoc_li_heading_level_3" role="treeitem" ><div role="presentation" ><span data-href='#2Waitforanyinputprocessor' data-hl='3'></span><a href='#2Waitforanyinputprocessor' id='2Waitforanyinputprocessor_toc_headding'>2) Wait for any input processor</a></div></li><li class="pac_dtoc_li_heading_level_3" role="treeitem" ><div role="presentation" ><span data-href='#3Waitforrequiredinputprocessors' data-hl='3'></span><a href='#3Waitforrequiredinputprocessors' id='3Waitforrequiredinputprocessors_toc_headding'>3) Wait for required input processors</a></div></li></ul><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#Timeoutsretriesandcontinueanyway' data-hl='2'></span><a href='#Timeoutsretriesandcontinueanyway' id='Timeoutsretriesandcontinueanyway_toc_headding'>Timeouts, retries, and “continue anyway”</a></div></li><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#Arealscenarioenrichingcatalogdatafromthreesources' data-hl='2'></span><a href='#Arealscenarioenrichingcatalogdatafromthreesources' id='Arealscenarioenrichingcatalogdatafromthreesources_toc_headding'>A real scenario: enriching catalog data from three sources</a></div></li><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#Filteringandenrichmentasfirstclassprocessors' data-hl='2'></span><a href='#Filteringandenrichmentasfirstclassprocessors' id='Filteringandenrichmentasfirstclassprocessors_toc_headding'>Filtering and enrichment as first-class processors</a></div></li><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#Whobenefits' data-hl='2'></span><a href='#Whobenefits' id='Whobenefits_toc_headding'>Who benefits?</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='#Developers' data-hl='3'></span><a href='#Developers' id='Developers_toc_headding'>Developers</a></div></li><li class="pac_dtoc_li_heading_level_3" role="treeitem" ><div role="presentation" ><span data-href='#Merchantsagencies' data-hl='3'></span><a href='#Merchantsagencies' id='Merchantsagencies_toc_headding'>Merchants &amp; agencies</a></div></li><li class="pac_dtoc_li_heading_level_3" role="treeitem" ><div role="presentation" ><span data-href='#Investors' data-hl='3'></span><a href='#Investors' id='Investors_toc_headding'>Investors</a></div></li></ul><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='#ReliabilityisnotmagicItspolicies' data-hl='2'></span><a href='#ReliabilityisnotmagicItspolicies' id='ReliabilityisnotmagicItspolicies_toc_headding'>Reliability is not magic. It’s policies.</a></div></li></ul></div>
            </div>
        </div>
        
				</div>
			</div>
			</div>
				
				
				
				
			</div><div class="et_pb_row et_pb_row_70">
				<div class="et_pb_column et_pb_column_4_4 et_pb_column_70  et_pb_css_mix_blend_mode_passthrough et-last-child">
				
				
				
				
				<div class="et_pb_module et_pb_blurb et_pb_blurb_136  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>Merge Processor: where parallelism meets reality</span></h2>
						<div class="et_pb_blurb_description"><p>In a composable pipeline, you often run things in parallel:</p>
<ul>
<li>fetch price from system A</li>
<li>fetch description from system B</li>
<li>fetch stock from system C</li>
</ul>
<p>Eventually, you need to bring results back together.</p>
<p>That’s what the <strong>Merge Processor</strong> does.</p>
<p>But the tricky part is: <em>how long do you wait, and what do you do when not everything arrives?</em></p>
<p>So Qilin supports different merge policies.</p></div>
					</div>
				</div>
			</div>
			</div>
				
				
				
				
			</div><div class="et_pb_row et_pb_row_71">
				<div class="et_pb_column et_pb_column_4_4 et_pb_column_71  et_pb_css_mix_blend_mode_passthrough et-last-child">
				
				
				
				
				<div class="et_pb_module et_pb_blurb et_pb_blurb_137  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>Three merge timeout policies (choose your philosophy)</span></h2>
						<div class="et_pb_blurb_description"><h3>1) Wait for all input processors (default)</h3>
<p>This is the “strict correctness” mode:</p>
<ul>
<li>Merge waits until <strong>all parent processors finish</strong></li>
<li>No timeout policy</li>
<li>Best when every input is required for a valid result</li>
</ul>
<p>Use this when incomplete data would be worse than delayed data.</p>
<h3>2) Wait for any input processor</h3>
<p>This is the “fast enough” mode:</p>
<ul>
<li>Merge starts a timeout countdown once <strong>any</strong> input finishes</li>
<li>When the timeout ends, merge proceeds with whatever results arrived</li>
</ul>
<p>Use this when you value speed and partial results are acceptable.</p>
<h3>3) Wait for required input processors</h3>
<p>This is the “hybrid” mode:</p>
<ul>
<li>define a list of required parents</li>
<li>wait for those to complete</li>
<li>start a timeout countdown afterward</li>
<li>proceed even if non-required inputs didn’t arrive</li>
</ul>
<p>Use this when some inputs are critical and others are optional enhancements.</p></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_138  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>Timeouts, retries, and “continue anyway”</span></h2>
						<div class="et_pb_blurb_description"><p>A timeout is not always a failure. Sometimes it’s just a signal.</p>
<p>So processors can be configured with:</p>
<ul>
<li><strong>TimeoutConfig</strong> (how long is “too long”)</li>
<li><strong>RetryConfig</strong> (how many times to retry and how long to wait between tries)</li>
<li><strong>OnErrorBehavior</strong> (continue vs stop)</li>
</ul>
<p>A simple retry policy looks like:</p>
<pre>"retryConfig": {
  "maximumRetries": 3,
  "retryAfterInSeconds": 3
}</pre>
<p>This gives you structured resilience without rewriting your own scheduler logic.</p></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_139  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>A real scenario: enriching catalog data from three sources</span></h2>
						<div class="et_pb_blurb_description"><p>Let’s say you enrich products using:</p>
<ul>
<li>ERP (core master data) → required</li>
<li>PIM (marketing text) → optional</li>
<li>Pricing service (dynamic pricing) → required</li>
</ul>
<p>A “required inputs” merge policy lets you:</p>
<ul>
<li>wait for ERP + pricing</li>
<li>proceed even if PIM is slow or unavailable</li>
<li>still produce a usable product update</li>
</ul>
<p>That’s a pipeline that keeps the business running without silently dropping correctness.</p></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_accordion et_pb_accordion_15">
				
				
				
				
				<div class="et_pb_toggle et_pb_module et_pb_accordion_item et_pb_accordion_item_15  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_140  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>Filtering and enrichment as first-class processors</span></h2>
						<div class="et_pb_blurb_description"><p>Alongside merge reliability, we’ve also been expanding processors that work directly with object content:</p>
<ul>
<li>content filtering based on reusable predicate logic</li>
<li>content enrichment designed to combine or augment fields</li>
</ul>
<p>The long-term goal: keep transformations inside the pipeline, where they can be tracked, tested, and maintained.</p></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_141  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>Who benefits?</span></h2>
						<div class="et_pb_blurb_description"><h3>Developers</h3>
<ul>
<li>clear semantics instead of “mystery retries”</li>
<li>consistent timeout and retry behavior across processors</li>
<li>less custom glue code for parallel fan-out / fan-in patterns</li>
</ul>
<h3>Merchants &amp; agencies</h3>
<ul>
<li>fewer brittle syncs that collapse when one dependency hiccups</li>
<li>pipelines that degrade gracefully under partial failure</li>
<li>easier troubleshooting because behavior is explicit, not implied</li>
</ul>
<h3>Investors</h3>
<p>Reliability features reduce operational cost and support load. They’re not just technical niceties &#8211; they’re economic multipliers.</p></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_142  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>Once you can merge and retry reliably, you can start making a new trade:</p>
<p><strong>batching vs real-time.</strong></p>
<p>July will introduce more around queue-based buffering &#8211; because sometimes the smartest pipeline isn’t the fastest one, it’s the one that ships in stable, cost-efficient chunks.</p></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_143  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>Reliability is not magic. It’s policies.</span></h2>
						<div class="et_pb_blurb_description"><p>The “old way” taught us the patterns.</p>
<p>Qilin.Cloud is turning those patterns into configurable primitives &#8211; so your pipelines can behave like experienced engineers wrote them… even when nobody is awake at 03:00 AM.</p></div>
					</div>
				</div>
			</div>
			</div>
				
				
				
				
			</div>
				
				
			</div>
<p>The post <a rel="nofollow" href="https://qilin.cloud/merge-timeouts-retries-reliability-patterns/">Merge, Timeouts, Retries: Reliability Patterns for Composable Pipelines</a> appeared first on <a rel="nofollow" href="https://qilin.cloud">Qilin.Cloud</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Webhook Entry &#038; HTTP Request: Turning Qilin.Cloud into an Integration Swiss Army Knife</title>
		<link>https://qilin.cloud/webhook-entry-http-request-turning-qilin-cloud-into-an-integration-swiss-army-knife/</link>
		
		<dc:creator><![CDATA[Dinh Vo]]></dc:creator>
		<pubDate>Sat, 31 May 2025 08:00:00 +0000</pubDate>
				<category><![CDATA[Product Updates]]></category>
		<category><![CDATA[credentials]]></category>
		<category><![CDATA[http]]></category>
		<category><![CDATA[integration]]></category>
		<category><![CDATA[processors]]></category>
		<category><![CDATA[webhools]]></category>
		<guid isPermaLink="false">https://qilin.cloud/?p=3653</guid>

					<description><![CDATA[<p>May’s update introduces two powerful processors: Webhook Entry to start pipelines from external events, and HTTP Request to call any API mid-flow—backed by reusable credential management.</p>
<p>The post <a rel="nofollow" href="https://qilin.cloud/webhook-entry-http-request-turning-qilin-cloud-into-an-integration-swiss-army-knife/">Webhook Entry &amp; HTTP Request: Turning Qilin.Cloud into an Integration Swiss Army Knife</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_9 et_section_regular" >
				
				
				
				
				
				
				<div class="et_pb_row et_pb_row_72">
				<div class="et_pb_column et_pb_column_4_4 et_pb_column_72  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>If you’ve built integrations for a while, you know the “classic” toolbox:</p>
<ul>
<li>cron jobs to trigger things</li>
<li>HTTP calls to stitch systems together</li>
<li>scripts that grow into… other scripts</li>
</ul>
<p>It’s a proud tradition. <br />It’s also how a lot of technical debt is born.</p>
<p>In May, we’ve been turning those classic patterns into <strong>first-class pipeline building blocks</strong> inside Qilin.Cloud:</p>
<ul>
<li><strong>Webhook Entry Processor</strong> → start a pipeline from an external event</li>
<li><strong>HTTP Request Processor</strong> → call any external API mid-pipeline</li>
<li><strong>Processor Credentials</strong> → manage auth once, reuse everywhere</li>
</ul>
<p>This is how Qilin becomes less “a platform you connect to” and more “a platform you build on”.</p></div>
			</div>
			</div>
				
				
				
				
			</div><div class="et_pb_row et_pb_row_73">
				<div class="et_pb_column et_pb_column_4_4 et_pb_column_73  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_9">
				
				
				
				
				
				
				<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='#WebhookEntryProcessoreventdrivenpipelineswithoutducttape' data-hl='2'></span><a href='#WebhookEntryProcessoreventdrivenpipelineswithoutducttape' id='WebhookEntryProcessoreventdrivenpipelineswithoutducttape_toc_headding'>Webhook Entry Processor: event-driven pipelines without duct tape</a></div></li><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#HTTPRequestProcessorcallingtheoutsideworldsafely' data-hl='2'></span><a href='#HTTPRequestProcessorcallingtheoutsideworldsafely' id='HTTPRequestProcessorcallingtheoutsideworldsafely_toc_headding'>HTTP Request Processor: calling the outside world (safely)</a></div></li><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#Credentialsstopcopypastingsecretsintoconfigurations' data-hl='2'></span><a href='#Credentialsstopcopypastingsecretsintoconfigurations' id='Credentialsstopcopypastingsecretsintoconfigurations_toc_headding'>Credentials: stop copy-pasting secrets into configurations</a></div></li><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#Arealpipelinescenariorepriceandpublish' data-hl='2'></span><a href='#Arealpipelinescenariorepriceandpublish' id='Arealpipelinescenariorepriceandpublish_toc_headding'>A real pipeline scenario: “reprice and publish”</a></div></li><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#Whobenefits' data-hl='2'></span><a href='#Whobenefits' id='Whobenefits_toc_headding'>Who benefits?</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='#Developers' data-hl='3'></span><a href='#Developers' id='Developers_toc_headding'>Developers</a></div></li><li class="pac_dtoc_li_heading_level_3" role="treeitem" ><div role="presentation" ><span data-href='#Merchantsagencies' data-hl='3'></span><a href='#Merchantsagencies' id='Merchantsagencies_toc_headding'>Merchants + agencies</a></div></li><li class="pac_dtoc_li_heading_level_3" role="treeitem" ><div role="presentation" ><span data-href='#Investors' data-hl='3'></span><a href='#Investors' id='Investors_toc_headding'>Investors</a></div></li></ul><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='#Buildintegrationsthewaywevealwayswantedto' data-hl='2'></span><a href='#Buildintegrationsthewaywevealwayswantedto' id='Buildintegrationsthewaywevealwayswantedto_toc_headding'>Build integrations the way we’ve always wanted to</a></div></li></ul></div>
            </div>
        </div>
        
				</div>
			</div>
			</div>
				
				
				
				
			</div><div class="et_pb_row et_pb_row_78">
				<div class="et_pb_column et_pb_column_4_4 et_pb_column_78  et_pb_css_mix_blend_mode_passthrough et-last-child">
				
				
				
				
				<div class="et_pb_module et_pb_blurb et_pb_blurb_151  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>Webhook Entry Processor: event-driven pipelines without duct tape</span></h2>
						<div class="et_pb_blurb_description"><p>A webhook is the digital version of a doorbell.</p>
<p>Instead of polling (“<em>did something change yet?</em>”), an external system rings the bell when it has something to say.</p>
<p>The Webhook Entry Processor gives you:</p>
<ul>
<li>a stable webhook entry point</li>
<li>authentication via a stored credential</li>
<li>a predictable way to transform incoming payload into a FlowObject</li>
</ul>
<p>A minimal config looks like:</p>
<pre>{
  "id": "Webhook_Entry_1",
  "type": "Qilin.WebhookEntry",
  "config": {
    "webhookId": "your-webhook-id",
    "credentialId": "credential-guid",
    "authType": "BasicAuth"
  }
}
</pre>
<p>Now your pipeline can start the moment something happens:</p>
<ul>
<li>price update from a repricer</li>
<li>order created in a shop system</li>
<li>ERP pushes a shipment status update</li>
<li>a partner system signals “new catalog batch ready”</li>
</ul>
<p>No cron job required. No polling tax.</p></div>
					</div>
				</div>
			</div>
			</div>
				
				
				
				
			</div><div class="et_pb_row et_pb_row_79">
				<div class="et_pb_column et_pb_column_4_4 et_pb_column_79  et_pb_css_mix_blend_mode_passthrough et-last-child">
				
				
				
				
				<div class="et_pb_module et_pb_blurb et_pb_blurb_152  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>HTTP Request Processor: calling the outside world (safely)</span></h2>
						<div class="et_pb_blurb_description"><p>The HTTP Request Processor is the workhorse for “call this API and use the result”.</p>
<p>It supports classic requirements you’d usually implement in custom code:</p>
<ul>
<li>method, URL, headers, query params</li>
<li>retries and retry intervals</li>
<li>timeouts</li>
<li>expected status codes</li>
<li>payload mapping from pipeline context (dynamic values)</li>
<li>optional authentication via stored credentials</li>
</ul>
<p>A simplified example:</p>
<pre>{
  "id": "Http_Request_1",
  "type": "Qilin.HttpRequest",
  "config": {
    "processorHttpMethod": "GET",
    "url": "https://api.example.com/products/{{FlowObjectContents.entry.sku}}",
    "expectedStatusCodes": [200],
    "timeoutInSeconds": 30,
    "retryTimes": 3
  }
}
</pre>
<p>So instead of writing a custom microservice for every “call an API” step, you can keep the logic inside the pipeline &#8211; auditable, trackable, and reusable.</p></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_153  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>Credentials: stop copy-pasting secrets into configurations</span></h2>
						<div class="et_pb_blurb_description"><p>HTTP calls and webhooks are only as good as their authentication.</p>
<p>And authentication is where teams often end up doing unsafe things because it’s “just faster”.</p>
<p>Qilin’s <strong>Processor Credentials</strong> are meant to restore sanity:</p>
<ul>
<li>credentials are created once</li>
<li>referenced by ID in processors</li>
<li>managed with permissions (RBAC)</li>
<li>reused across pipelines consistently</li>
</ul>
<p>Credential types can represent common auth patterns, for example:</p>
<ul>
<li>Basic authentication</li>
<li>header-based API keys</li>
<li>OAuth2 client credentials</li>
<li>SMTP / email provider credentials (more on that later this year)</li>
</ul>
<p>That keeps secrets out of pipeline definitions &#8211; and makes it easier to rotate credentials without rewriting everything.</p></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_154  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>A real pipeline scenario: “reprice and publish”</span></h2>
						<div class="et_pb_blurb_description"><p>Imagine this flow:</p>
<ol>
<li>repricer sends a webhook with SKU + new price</li>
<li>pipeline validates the payload</li>
<li>pipeline calls ERP via HTTP Request Processor to fetch product context</li>
<li>pipeline enriches and maps data</li>
<li>pipeline exports updated offer to a marketplace connector</li>
</ol>
<p>In the old world, that’s:</p>
<ul>
<li>a webhook endpoint service</li>
<li>an HTTP client service</li>
<li>a mapping layer</li>
<li>plus monitoring glue</li>
</ul>
<p>In Qilin.Cloud, it becomes a pipeline.</p></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_accordion et_pb_accordion_17">
				
				
				
				
				<div class="et_pb_toggle et_pb_module et_pb_accordion_item et_pb_accordion_item_17  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_155  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>Who benefits?</span></h2>
						<div class="et_pb_blurb_description"><h3>Developers</h3>
<ul>
<li>fewer one-off services</li>
<li>consistent retry + timeout behavior across integrations</li>
<li>observable steps (not “black box code”)</li>
<li>credential reuse without leaking secrets into configs</li>
</ul>
<h3>Merchants + agencies</h3>
<ul>
<li>faster delivery of custom flows</li>
<li>less infrastructure to host and maintain</li>
<li>easier handover because the logic is visible in the platform</li>
</ul>
<h3>Investors</h3>
<p>This is platform extensibility. Every reusable processor reduces implementation effort per customer and increases the range of use cases Qilin can serve.</p></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_156  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>Once you can trigger flows and call APIs, you quickly need a third thing:</p>
<p><strong>how to combine results reliably.</strong></p>
<p>Next month we’ll explore merge strategies, retry patterns, and the reliability primitives that make complex pipelines behave like adults.</p></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_157  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>Build integrations the way we’ve always wanted to</span></h2>
						<div class="et_pb_blurb_description"><p>This isn’t a rejection of the old way.</p>
<p>It’s the old way &#8211; webhooks, HTTP calls, credentials, retries &#8211; captured as reusable building blocks.</p>
<p>Same wisdom. Less duct tape.</p></div>
					</div>
				</div>
			</div>
			</div>
				
				
				
				
			</div>
				
				
			</div>
<p>The post <a rel="nofollow" href="https://qilin.cloud/webhook-entry-http-request-turning-qilin-cloud-into-an-integration-swiss-army-knife/">Webhook Entry &amp; HTTP Request: Turning Qilin.Cloud into an Integration Swiss Army Knife</a> appeared first on <a rel="nofollow" href="https://qilin.cloud">Qilin.Cloud</a>.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
