<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
  <channel>
    <title>Univio - Tech blog</title>
    <link>https://tech.univio.com</link>
    <description>Expert insights on B2B e-commerce, PIM, CMS, system integration, cloud, data and AI. Practical guides for digital transformation.</description>
    <language>en</language>
    <pubDate>Wed, 14 Oct 2026 11:18:39 GMT</pubDate>
    <dc:date>2026-10-14T11:18:39Z</dc:date>
    <dc:language>en</dc:language>
    <item>
      <title>The Art of Choosing the Right Model. Why We Created the Commerce &amp; Enterprise Benchmark (CEB)</title>
      <link>https://tech.univio.com/the-art-of-choosting-the-right-model</link>
      <description>&lt;div class="hs-featured-image-wrapper"&gt; 
 &lt;a href="https://tech.univio.com/the-art-of-choosting-the-right-model?hsLang=en" title="" class="hs-featured-image-link"&gt; &lt;img src="https://tech.univio.com/hubfs/wadki_AI_v1-2.png" alt="The Art of Choosing the Right Model. Why We Created the Commerce &amp;amp; Enterprise Benchmark (CEB)" class="hs-featured-image" style="width:auto !important; max-width:50%; float:left; margin:0 15px 15px 0;"&gt; &lt;/a&gt; 
&lt;/div&gt; 
&lt;p&gt;Choosing an AI model for production systems rarely is rarely just a matter of down to a simple comparison of charts on public leaderboards. Vendor marketing promises and academic tests rarely answer the key questions: how a given LLM will handle our specific tasks, how much it will cost to execute them, and what the quality of the output will be. Evaluation only becomes valuable when it reflects the actual environment in which the system is supposed to operate, tackling problems and datasets aligned with our needs.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;Choosing an AI model for production systems rarely is rarely just a matter of down to a simple comparison of charts on public leaderboards. Vendor marketing promises and academic tests rarely answer the key questions: how a given LLM will handle our specific tasks, how much it will cost to execute them, and what the quality of the output will be. Evaluation only becomes valuable when it reflects the actual environment in which the system is supposed to operate, tackling problems and datasets aligned with our needs.&lt;/p&gt; 
&lt;p&gt;The Commerce &amp;amp; Enterprise Benchmark (CEB for short) addresses these challenges in a single evaluation suite. It provides a reproducible way to test the capabilities and limitations of AI systems using tasks relevant to Commerce &amp;amp; Enterprise solutions.&lt;/p&gt; 
&lt;h2&gt;&lt;strong&gt;Why did we create our own AI benchmark?&lt;/strong&gt;&lt;/h2&gt; 
&lt;p&gt;CEB is a tool we created for our own needs to reproducibly test the real-world capabilities of models, agents, and evaluation harnesses in our daily engineering work at Univio. Today, we are opening it up and sharing our insights publicly.&lt;/p&gt; 
&lt;p&gt;A large portion of existing benchmarks relies on synthetic data and public datasets. Unsurprisingly, models are trained on this exact same data. In many cases, models rank high on leaderboards simply because they memorized the questions during training (i.e., data contamination, meaning the leakage of test data into training sets). As a result, public benchmarks often measure a model's memory rather than its reasoning capabilities.&lt;/p&gt; 
&lt;p&gt;A stellar score in SWE-bench, MMLU, or GSM8K does not translate to whether the model will correctly decline a Polish surname, work efficiently with Jira and HubSpot, or maintain document consistency after tens of edits.&lt;/p&gt; 
&lt;p&gt;Public leaderboards and CEB operate in entirely different domains. The former frequently measure universal academic competencies. We measure the models' effectiveness in solving problems encountered in e-commerce and enterprise organisations.&lt;/p&gt; 
&lt;h2&gt;What is CEB?&lt;/h2&gt; 
&lt;p&gt;It is a closed set of tasks selected from real-world problems encountered by Univio employees and our partners. The test architecture is based on Inspect AI from the UK AI Safety Institute.&lt;/p&gt; 
&lt;p&gt;Coding tasks are run in isolated sandboxes.&lt;/p&gt; 
&lt;h3&gt;What exactly do we evaluate?&lt;/h3&gt; 
&lt;p&gt;We apply a range of evaluation dimensions:&lt;/p&gt; 
&lt;ul style="list-style-type: square;"&gt; 
 &lt;li&gt;&lt;span style="color: #d51313;"&gt;Linguistic tasks:&lt;/span&gt; declension, spelling, punctuation, and vocabulary comprehension, verified independently for Polish, English, and German.&lt;/li&gt; 
 &lt;li&gt;&lt;span style="color: #d51313;"&gt;Long context and editing consistency: &lt;/span&gt;multimodal operations and handling tasks that exceed the allowable context window size.&lt;/li&gt; 
 &lt;li&gt;&lt;span style="color: #d51313;"&gt;Working with data, business tools, and technical integrations:&lt;/span&gt; e.g., Jira, Confluence, HubSpot, Excel.&lt;/li&gt; 
 &lt;li style="color: #d51313;"&gt;&lt;span style="color: #d51313;"&gt;Working with structured data and data contracts.&lt;/span&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;span style="color: #d51313;"&gt;&lt;strong&gt;Fact validation:&lt;/strong&gt;&lt;/span&gt; knowledge tests identifying the model's knowledge cutoff and specialized domain expertise.&lt;/li&gt; 
 &lt;li&gt;&lt;span style="color: #d51313;"&gt;Coding and automation: &lt;/span&gt;currently analyzed in JS, Python, and PHP.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Thanks to the private nature of the benchmark, our test data does not end up in public training corpora. We do not use synthetic data; we rely on real problems that have been anonymized and encapsulated into test cases.&lt;/p&gt; 
&lt;p&gt;In addition to scoring the results, we also calculate the number of tokens used and their cost. We record the execution time of the test, but we do not factor it into the rankings—we don't consider it a reliable metric when inference is handled over a network.&lt;/p&gt; 
&lt;p&gt;Our goal is an objective measurement of a model's true competencies in commercial applications.&lt;/p&gt; 
&lt;h3&gt;&lt;strong&gt;What does CEB not do?&lt;/strong&gt;&lt;/h3&gt; 
&lt;p&gt;We do not treat our benchmark as a universal ranking for every use case. We are also aware of its current limitations; for example, the task database for the German language is currently too small to draw conclusive results, but we are constantly expanding it.&lt;/p&gt; 
&lt;p&gt;We are also not looking for a perfect model for everything. We are looking for optimal solutions for specific use cases and budgets.&lt;/p&gt; 
&lt;p&gt;We regularly test AI model performance across various use cases and sectors. Curious how the ones you use at work are doing? We’d gladly compare our findings with your industry and needs. Contact us!&lt;/p&gt;  
&lt;img src="https://track.hubspot.com/__ptq.gif?a=4709516&amp;amp;k=14&amp;amp;r=https%3A%2F%2Ftech.univio.com%2Fthe-art-of-choosting-the-right-model&amp;amp;bu=https%253A%252F%252Ftech.univio.com&amp;amp;bvt=rss" alt="" width="1" height="1" style="min-height:1px!important;width:1px!important;border-width:0!important;margin-top:0!important;margin-bottom:0!important;margin-right:0!important;margin-left:0!important;padding-top:0!important;padding-bottom:0!important;padding-right:0!important;padding-left:0!important; "&gt;</content:encoded>
      <category>DevOps</category>
      <category>AI &amp; ML</category>
      <pubDate>Fri, 09 Oct 2026 13:36:53 GMT</pubDate>
      <author>lukasz.biegaj@univio.com (Łukasz Biegaj)</author>
      <guid>https://tech.univio.com/the-art-of-choosting-the-right-model</guid>
      <dc:date>2026-10-09T13:36:53Z</dc:date>
    </item>
    <item>
      <title>Leveraging KV Cache for Efficient Programming with LLMs</title>
      <link>https://tech.univio.com/leveraging-kv-cache-for-efficient-programming-with-llms</link>
      <description>&lt;div class="hs-featured-image-wrapper"&gt; 
 &lt;a href="https://tech.univio.com/leveraging-kv-cache-for-efficient-programming-with-llms?hsLang=en" title="" class="hs-featured-image-link"&gt; &lt;img src="https://tech.univio.com/hubfs/KV%20Cache%20cover-1.png" alt="Leveraging KV Cache for Efficient Programming with LLMs" class="hs-featured-image" style="width:auto !important; max-width:50%; float:left; margin:0 15px 15px 0;"&gt; &lt;/a&gt; 
&lt;/div&gt; 
&lt;p&gt;Caching is a concept every developer knows well: we store the result of an operation so we don't have to recompute it on the next request. A similar mechanism works with equal success in large language models. In the LLM world, the counterpart to cache memory is &lt;strong&gt;KV Cache (Key-Value Cache)&lt;/strong&gt;. While it operates under the hood, understanding it helps you run models faster, more efficiently, and at a significantly lower cost.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;Caching is a concept every developer knows well: we store the result of an operation so we don't have to recompute it on the next request. A similar mechanism works with equal success in large language models. In the LLM world, the counterpart to cache memory is &lt;strong&gt;KV Cache (Key-Value Cache)&lt;/strong&gt;. While it operates under the hood, understanding it helps you run models faster, more efficiently, and at a significantly lower cost.&lt;/p&gt;  
&lt;h2&gt;How Does an LLM Remember Context?&lt;/h2&gt; 
&lt;p&gt;Let's start with a bit of theory. When a query hits a Transformer-based LLM, it passes through two main phases (assuming the model runs on a GPU):&lt;br&gt;&lt;br&gt;&lt;span style="color: #d51313;"&gt;Phase I: Prefill.&lt;/span&gt;&lt;br&gt;This involves processing the entire input prompt using the full compute power of the GPU. During this phase, Key-Value (KV) states are calculated and saved in memory for every token. Put simply: K (Key) answers what a given token represents, while V (Value) carries what content it holds. The memory used here is the GPU's VRAM. Processing in this phase happens in parallel.&lt;br&gt;&lt;br&gt;&lt;span style="color: #d51313;"&gt;Phase II: Decoding.&lt;/span&gt;&lt;br&gt;This is the stage where the model generates its response token by token. As it generates each new token, it reaches into the previously allocated VRAM to read back the existing KV pairs. This reveals a clear difference in execution profile: the prefill phase is heavily GPU-bound, whereas the decoding phase is memory-bound.&lt;br&gt;&lt;br&gt;To visualize this read/write flow, take a look at the concept below:&lt;/p&gt; 
&lt;p&gt;The diagram above illustrates a simplified conversation flow with a model. In turn 1, the model must process all input tokens during the prefill phase and write them into the KV Cache. In turn 2, it begins generation right from token #5, fetching the prior conversation (including its own previous outputs) directly from cache memory.&lt;/p&gt; 
&lt;h2&gt;Is Caching Available in Every Model?&lt;/h2&gt; 
&lt;p&gt;KV Cache is a foundational component of every Transformer-based LLM system. While you can influence how it behaves, your degree of control depends on how you interact with the model:&lt;/p&gt; 
&lt;ul style="list-style-type: square;"&gt; 
 &lt;li&gt; &lt;p&gt;Directly via API: when manually constructing the system prompt, tool definitions, and user prompts.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Through ready-made agentic frameworks: such as Claude Code.&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Different model providers offer varying levels of control. Anthropic is a great example: when querying their models directly via API, you can pass a cache_control parameter to explicitly mark which blocks of context should be cached. This provides far more granular control than relying on high-level agentic wrappers.&lt;/p&gt; 
&lt;h2&gt;Putting KV Cache Knowledge into Practice&lt;/h2&gt; 
&lt;p&gt;Let's look at a practical example using Claude Code and custom AI harness development. The context window passed on every request typically consists of three main parts:&lt;/p&gt; 
&lt;ul style="list-style-type: square;"&gt; 
 &lt;li&gt; &lt;p&gt;System prompt – primary instructions and tool definitions.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Project context – files like CLAUDE.md and project-specific guidelines.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Conversation history – the most dynamic section.&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;Each part has a distinct lifecycle. In an ideal world, everything would remain static, resulting in a 100% cache hit rate on every request. In reality, that's impossible—conversation history naturally grows with every turn.&lt;/p&gt; 
&lt;p&gt;That is why keeping the system and project layers as static as possible is crucial. Avoid embedding dynamic data into these early sections—such as real-time timestamps or dynamically generated directory trees. Any change in the prefix automatically invalidates the entire downstream cache.&lt;/p&gt; 
&lt;p&gt;Beyond prompt edits, specific environment actions will also clear your cache:&lt;/p&gt; 
&lt;ul style="list-style-type: square;"&gt; 
 &lt;li&gt; &lt;p&gt;Changing models or adjusting the reasoning depth (Effort level).&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Adding or removing MCP servers (which mutates tool definitions in the system prompt).&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Toggling plugins on or off.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Executing commands like /clear or /compact (which reload project rules).&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Uploading large attachments (images, PDFs) that exceed provider caching thresholds.&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;It's also worth noting how caching works across multi-session setups on a single machine. Sessions running in the same working directory share the same cache. If you spin up sub-agents, each sub-agent maintains its own isolated cache—it doesn't pollute or automatically inherit from the parent agent. Only explicit commands like /fork will copy the parent's cache state over to a new sub-agent.&lt;/p&gt; 
&lt;p&gt;Finally, cache has a shelf life. Extended periods of inactivity mean the provider eventually drops it from memory. This window is governed by a TTL (Time To Live) parameter, which usually ranges from 5 minutes to 1 hour depending on the provider and tier.&lt;/p&gt; 
&lt;h2&gt;How KV Cache Impacts Token Costs&lt;/h2&gt; 
&lt;p&gt;Your context memory strategy directly impacts your API bills. The rate for an initial call (a full prefill with zero cache hits) is higher than subsequent requests that hit the cache.&lt;/p&gt; 
&lt;p&gt;Looking at the pricing structure above, writing to the cache (&lt;code&gt;Prompt Caching / Write&lt;/code&gt;) incurs a slight premium over standard base tokens. However, the real savings hit when a query lands a cache hit reducing the cost to a fraction of the base rate ($0.25). The 5-minute and 1-hour write options simply correspond to different TTL retention settings.&lt;/p&gt; 
&lt;h2&gt;Benchmarks: KV Cache in Action&lt;/h2&gt; 
&lt;p&gt;To verify the theory in practice, I ran a benchmark measuring response times on repeated requests across two setup types:&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;Bielik-4.5B&lt;/strong&gt; – running locally via Ollama on CPU.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;&lt;strong&gt;GPT-5-mini&lt;/strong&gt; – queried via an enterprise AI Gateway.&lt;/p&gt; &lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;Both tests track TTFT (Time To First Token) using a fixed prefix containing a question. The prefix length must exceed 1,024 tokens; below this threshold, caching overhead outweighs performance gains.&lt;/p&gt; 
&lt;table&gt; 
 &lt;tbody&gt; 
  &lt;tr&gt; 
   &lt;td&gt; &lt;p&gt;Parametr&lt;/p&gt; &lt;/td&gt; 
   &lt;td&gt; &lt;p&gt;Test 1 — Bielik (lokalnie, Ollama/CPU)&lt;/p&gt; &lt;/td&gt; 
   &lt;td&gt; &lt;p&gt;Test 2 — GPT (gpt-5-mini)&lt;/p&gt; &lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt; &lt;p&gt;Turn 1 cold (TTFT)&lt;/p&gt; &lt;/td&gt; 
   &lt;td&gt; &lt;p&gt;45 501 ms&lt;/p&gt; &lt;/td&gt; 
   &lt;td&gt; &lt;p&gt;5 257 ms&lt;/p&gt; &lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt; &lt;p&gt;Turn 2 hot (TTFT)&lt;/p&gt; &lt;/td&gt; 
   &lt;td&gt; &lt;p&gt;2 833 ms&lt;/p&gt; &lt;/td&gt; 
   &lt;td&gt; &lt;p&gt;3 112 ms&lt;/p&gt; &lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt; &lt;p&gt;Różnica czasu&lt;/p&gt; &lt;/td&gt; 
   &lt;td&gt; &lt;p&gt;−42 668 ms (szybciej o ~93,8%)&lt;/p&gt; &lt;/td&gt; 
   &lt;td&gt; &lt;p&gt;−2 145 ms (szybciej o ~40,8%)&lt;/p&gt; &lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt; &lt;p&gt;Hit 1 (cached_tokens)&lt;/p&gt; &lt;/td&gt; 
   &lt;td&gt; &lt;p&gt;brak danych&lt;/p&gt; &lt;/td&gt; 
   &lt;td&gt; &lt;p&gt;0&lt;/p&gt; &lt;/td&gt; 
  &lt;/tr&gt; 
  &lt;tr&gt; 
   &lt;td&gt; &lt;p&gt;Hit 2 (cached_tokens)&lt;/p&gt; &lt;/td&gt; 
   &lt;td&gt; &lt;p&gt;brak danych&lt;/p&gt; &lt;/td&gt; 
   &lt;td&gt; &lt;p&gt;17 920 (99,4% prefiksu)&lt;/p&gt; &lt;/td&gt; 
  &lt;/tr&gt; 
 &lt;/tbody&gt; 
&lt;/table&gt; 
&lt;p&gt;Both tests demonstrate a significant drop in TTFT when the prompt prefix is reused.&lt;br&gt;&lt;br&gt;With GPT-5-mini, we get explicit confirmation via the cached_tokens metric (17,920 tokens read straight from cache). Ollama doesn't expose this metric directly, but the performance leap speaks for itself. The high initial latency for Bielik stems from CPU inference limitations—that massive 93.8% drop reflects how painfully slow an un-cached CPU Prefill phase is, rather than proof that local caching is inherently superior.&lt;/p&gt; 
&lt;h2&gt;Key Takeaways&lt;/h2&gt; 
&lt;p&gt;Although the low-level caching engine remains hidden, you can directly influence how effectively it works:&lt;/p&gt; 
&lt;ul style="list-style-type: square;"&gt; 
 &lt;li&gt; &lt;p&gt;Minimize dynamic elements in static context zones (system prompts, project setups) to maximize cache hit rates.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Project configuration files (like CLAUDE.md) affect cache invalidation just as much as main prompt text.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Direct API calls grant much tighter control over cache break points than out-of-the-box agentic frameworks.&lt;/p&gt; &lt;/li&gt; 
 &lt;li&gt; &lt;p&gt;Design workflows around TTL limits so you don't lose cached states during long pauses between requests.&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt;  
&lt;img src="https://track.hubspot.com/__ptq.gif?a=4709516&amp;amp;k=14&amp;amp;r=https%3A%2F%2Ftech.univio.com%2Fleveraging-kv-cache-for-efficient-programming-with-llms&amp;amp;bu=https%253A%252F%252Ftech.univio.com&amp;amp;bvt=rss" alt="" width="1" height="1" style="min-height:1px!important;width:1px!important;border-width:0!important;margin-top:0!important;margin-bottom:0!important;margin-right:0!important;margin-left:0!important;padding-top:0!important;padding-bottom:0!important;padding-right:0!important;padding-left:0!important; "&gt;</content:encoded>
      <category>Backend &amp; Data</category>
      <category>AI &amp; ML</category>
      <pubDate>Fri, 09 Oct 2026 13:16:47 GMT</pubDate>
      <guid>https://tech.univio.com/leveraging-kv-cache-for-efficient-programming-with-llms</guid>
      <dc:date>2026-10-09T13:16:47Z</dc:date>
      <dc:creator>Michał Pawlik</dc:creator>
    </item>
    <item>
      <title>Performing SaaS application background tasks with AWS Batch and AWS Step Functions</title>
      <link>https://tech.univio.com/platforming-saas-application-background-tasks</link>
      <description>&lt;div class="hs-featured-image-wrapper"&gt; 
 &lt;a href="https://tech.univio.com/platforming-saas-application-background-tasks?hsLang=en" title="" class="hs-featured-image-link"&gt; &lt;img src="https://tech.univio.com/hubfs/unity_220606_unity_team_of_teams_v1-kopia-2%20(1)-1.png" alt="Performing SaaS application background tasks with AWS Batch and AWS Step Functions" class="hs-featured-image" style="width:auto !important; max-width:50%; float:left; margin:0 15px 15px 0;"&gt; &lt;/a&gt; 
&lt;/div&gt; 
&lt;p style="color: #181716; background-color: #ffffff;"&gt;Even the tiniest web application has to perform a lot of background tasks, be it image resizing, product/stock imports and report or sitemap generation. In addition, if your product is distributed in SaaS model, then most of them have to be performed for each of your customers.&lt;/p&gt;</description>
      <content:encoded>&lt;p style="color: #181716; background-color: #ffffff;"&gt;Even the tiniest web application has to perform a lot of background tasks, be it image resizing, product/stock imports and report or sitemap generation. In addition, if your product is distributed in SaaS model, then most of them have to be performed for each of your customers.&lt;/p&gt; 
&lt;p style="color: #181716; background-color: #ffffff;"&gt;That, depending on how popular your product is, may in turn require tons of computing power. You will have to find a way to quickly add and maintain all kinds of jobs, without adding too much technical debt to the project.&lt;/p&gt; 
&lt;p style="color: #181716; background-color: #ffffff;"&gt;Oh, and without blowing your application up whenever a heavy job is running.&lt;/p&gt; 
&lt;p style="color: #181716; background-color: #ffffff;"&gt;&lt;span style="color: #d51313;"&gt;At first, it may be tempting to just let the web application be their executor and scheduler.&lt;/span&gt; Add an @Scheduled annotation, if you live in Java’s world, or a node-cron and voila – your application has a background tasks mechanism.&lt;/p&gt; 
&lt;p style="color: #181716; background-color: #ffffff;"&gt;&lt;span style="color: #d51313;"&gt;It works fine… but it also causes some fundamental problems.&lt;/span&gt; As soon as you run a second instance of your application, you have to synchronize your state between apps, otherwise you schedule the same task twice. Even worse – any fluctuations of resource usage (a “busy” task or a sudden spike in requests) can heavily impact the performance of the application. &lt;span style="color: #d51313;"&gt;Your service could end up unreachable for end users, because a very CPU heavy task has consumed all the resources.&lt;/span&gt; This is nothing short of a nightmare, especially in the SaaS world with &lt;span style="color: #d51313;"&gt;“noisy neighbors”&lt;/span&gt;.&lt;/p&gt; 
&lt;p style="color: #181716; background-color: #ffffff;"&gt;Of course, you may add a synchronization mechanism between the tasks (and also code all the failure handling, retries or internal queues), schedule them to process only at night and so on. This is often the fastest method, but it leaves you with huge technical debt and does not scale too well.&lt;/p&gt; 
&lt;p style="color: #181716; background-color: #ffffff;"&gt;&lt;strong&gt;Can you do better?&lt;/strong&gt; Well, you may &lt;span style="color: #d51313;"&gt;split your app into an app-web and app-worker and detach the latter from handling the web requests&lt;/span&gt;. Various frameworks like Django support this, although it requires running queues like Celery or RabbitMQ. Now, the failures and memory errors of your tasks no longer affect end users. Surprise traffic spikes don’t suddenly blow up your background task. This is way better, but still requires you to manage and scale the worker cluster on demand. There is also a lot of shared code between the app-web and app-worker, which could both confuse developers and further grow the technical debt.&lt;/p&gt; 
&lt;p style="color: #181716; background-color: #ffffff;"&gt;&lt;strong&gt;Can you do (even) better?&lt;/strong&gt; &lt;span style="color: #d51313;"&gt;Well, why not let the web applications do the web part only? Let the worker applications be truly workers?&lt;/span&gt; Bind your tasks into lightweight, abstract containers that are ran on-demand, when necessary, with all the metadata collected from the outside. This is a common pattern in the data engineering/science world, where a huge DAG (directed acyclic graph) of various connected tasks is scheduled and executed on a daily basis. Using the right tools, you don’t need to be a data engineer to bring such quality into our web applications – you just need to use the cloud to its full extent.&lt;/p&gt; 
&lt;p style="color: #181716; background-color: #ffffff;"&gt;To achieve this, two major pieces are needed:&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li style="color: #181716; background-color: #ffffff;"&gt;First, an easy to use container environment, which automatically provides compute resources and runs containerized jobs.&lt;/li&gt; 
 &lt;li style="color: #181716; background-color: #ffffff;"&gt;Second, something to orchestrate the entire process. Thankfully, AWS has got us covered, specifically with the two technologies mentioned in the article’s title (a surprise huh?).&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p style="color: #181716; background-color: #ffffff;"&gt;&lt;strong&gt;AWS Batch&lt;/strong&gt; is, as the name suggests, a batch processing service. It is able to run hundreds of containers, providing as many compute resources as necessary. With its built-in queue all you need to do is define and trigger a job. AWS Batch will handle the execution part for you.&lt;/p&gt; 
&lt;p style="color: #181716; background-color: #ffffff;"&gt;&lt;strong&gt;AWS Step Functions&lt;/strong&gt; is an orchestrating service, based on a state machine. We define what should happen and in what order. The “what” could be a Lambda Function, a Fargate container, an AWS Glue job or an AWS Batch job (among few others). Step Functions (SFN) trigger all necessary “whats”, pass data between them, are able to run tasks in parallel, have some branching if/else logic and can be scheduled as needed.&lt;/p&gt; 
&lt;h2 style="color: #181716; background-color: #ffffff;"&gt;The know-how&lt;/h2&gt; 
&lt;h3 style="color: #181716; background-color: #ffffff;"&gt;The components&lt;/h3&gt; 
&lt;p style="color: #181716; background-color: #ffffff;"&gt;The architecture below is generic and works in most of our tasks. You will be able to abstract the logic concerning your particular task and reuse literally 90% of your Infrastructure as Code (IaC) whenever you encounter a similar problem. As always, CDK or Terraform is great and you should definitely use it.&lt;/p&gt; 
&lt;p style="color: #181716; background-color: #ffffff;"&gt;The general idea is:&lt;/p&gt; 
&lt;ul style="list-style-type: square;"&gt; 
 &lt;li style="color: #181716; background-color: #ffffff;"&gt; &lt;p style="color: #181716; background-color: #ffffff;"&gt;Chunk the job into smaller, parallelizable parts (this is a piece of cake in SaaS applications – you could just run the same job for each tenant)&lt;/p&gt; &lt;/li&gt; 
 &lt;li style="color: #181716; background-color: #ffffff;"&gt; &lt;p style="color: #181716; background-color: #ffffff;"&gt;Run each of them in a separate container&lt;/p&gt; &lt;/li&gt; 
 &lt;li style="color: #181716; background-color: #ffffff;"&gt; &lt;p style="color: #181716; background-color: #ffffff;"&gt;Have the entire process scheduled, if necessary&lt;br&gt;&lt;br&gt;&lt;/p&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2 style="color: #181716; background-color: #ffffff;"&gt;Metadata Lambda&lt;/h2&gt; 
&lt;p style="color: #181716; background-color: #ffffff;"&gt;As a starting point to our workflow, &lt;span style="color: #d51313;"&gt;we have a Lambda Function for deciding how many tasks AWS Batch needs to run&lt;/span&gt;. This entirely depends on your use case – if the task is to resize images then “a portion of the job” could be an array with a thousand ids. Each container would get thousands of photos to process – all unique to that respective container, too. If a sitemap is to be generated or products are to be imported, then one task could handle exactly one tenant.&lt;/p&gt; 
&lt;p style="color: #181716; background-color: #ffffff;"&gt;This is also a good place to handle any special logic – maybe some of your tenants require more parameters? What if a few of them should be ignored? Was the last execution for a given tenant successful and further computations are unnecessary for now? Answer similar questions yourself and code the logic accordingly. &lt;span style="color: #d51313;"&gt;Do also note that this could be a container instead of a Lambda if 15 minutes of execution time is not enough to decide how big your job should be.&lt;/span&gt;&lt;/p&gt; 
&lt;p style="color: #181716; background-color: #ffffff;"&gt;The metadata Lambda generates n sets of parameters (each set corresponds to “a portion of the job”) and saves them to an S3 bucket. We could also let the Step Functions pass the output from Lambda directly to AWS Batch (with no S3 involved), but there are various limits on how big (in kilobytes) the Step Function’s state can get. Our solution is more future-proof.&lt;/p&gt; 
&lt;br&gt; 
&lt;h2 style="color: #181716; background-color: #ffffff;"&gt;Batch Job and the Container&lt;/h2&gt; 
&lt;p style="color: #181716; background-color: #ffffff;"&gt;Batch Job Definition is rather straightforward – all you need to specify is how much vCPU or memory will be used by a single ECS Task, as well as the its specific Docker image. The type of the job we are using here is called Array Job – n parallel independent containers are to be run on the Compute Environment.&lt;/p&gt; 
&lt;p style="color: #181716; background-color: #ffffff;"&gt;&lt;span style="color: #d51313;"&gt;The container is a tiny application and its sole purpose is to run the parameterized task it was designed to perform, exiting after the work is done.&lt;/span&gt; Consequently, the app often resembles more of a script-ish file than a fully-fledged application.&lt;/p&gt; 
&lt;p style="color: #181716; background-color: #ffffff;"&gt;Furthermore, the code inside has to be as generic and reusable as possible – no hardcoding allowed! The first step is to read the S3 Bucket file using the AWS_BATCH_JOB_ARRAY_INDEX environment variable to get exact parameters – each container instance has its own unique number. That file, created by Lambda, should contain all the information required by the task – such as the tenant name, tenant bucket name and a thousand image IDs to process.&lt;/p&gt; 
&lt;p style="color: #181716; background-color: #ffffff;"&gt;&amp;nbsp;&lt;/p&gt; 
&lt;h2 style="color: #181716; background-color: #ffffff;"&gt;Batch Compute Environment and Job Queue&lt;/h2&gt; 
&lt;p style="color: #181716; background-color: #ffffff;"&gt;After the Batch Job is scheduled, the tasks are put into the Job Queue, where they wait be executed on a Compute Environment. These are pretty much ECS Clusters mixed with ASG/Spot Fleet and come in different colors and sizes types – you can either use your own ECS Cluster or let Batch manage the ECS Cluster for you. We have been successfully using Batch-managed clusters with Spot Instances to save some pennies. You only need to specify the minimum and maximum number of vCPUs. If you set the minimum to 0, the cluster will automatically scale its resources to nothing if no jobs are running. Pay as you go!&lt;/p&gt; 
&lt;p style="color: #181716; background-color: #ffffff;"&gt;You can also indirectly define the maximum parallelization of jobs here – if a container requires 4 vCPU, your cluster is using a maximum of 2 EC2 instances with 4 vCPU each, then at any given moment, at most, 2 tasks will be running. The rest of them will gently wait in the Job Queue to be picked up and processed at a later time. Similar reasoning can be applied with Memory. This is a great way to ensure you don’t kill your database or other resources.&lt;/p&gt;    
&lt;p style="color: #181716; background-color: #ffffff;"&gt;It might be worth noting that &lt;span style="color: #d51313;"&gt;a Job Queue can have multiple Compute Environments assigned&lt;/span&gt;. You may try running your job on spot instances first (using arbitrary Compute Environment A), but if no resources are available fallback to on demand ones (using Compute Environment B). You can also specify multiple EC2 instance types a Compute Environment is allowed to run. Depending on the workload AWS Batch will try to acquire an instance suited to the current demand in the Job Queue.&lt;/p&gt; 
&lt;h3 style="color: #181716; background-color: #ffffff;"&gt;Step Functions workflow&lt;/h3&gt; 
&lt;p style="color: #181716; background-color: #ffffff;"&gt;&lt;span style="color: #d51313;"&gt;Step Function governs the entire process, gluing other components together. With its rich integrations with other AWS Services you are able to trigger a Lambda function (or a Fargate container) and schedule a Batch Job.&lt;/span&gt; You define the entire workflow and its order of execution here, in the State Machine. Should the workflow fail at some point, you could also define an error handler. Our example is rather simple, but you might for example want to store all failures and successes in a database for historic reasons, perform more tasks after the Array Job is finished, send an email to each tenant or trigger analytic jobs in AWS Glue. Possibilities are nearly endless.&lt;/p&gt; 
&lt;br&gt; 
&lt;h2 style="color: #181716; background-color: #ffffff;"&gt;Other Batch functionalities&lt;/h2&gt; 
&lt;p style="color: #181716; background-color: #ffffff;"&gt;We have shown a rather simple workflow – an array of parallel, independent jobs. Batch itself provides more capabilities. Jobs can be dependent of each other and pass parameters within AWS Batch itself.&lt;/p&gt; 
&lt;h3 style="color: #181716; background-color: #ffffff;"&gt;&lt;strong&gt;N to N jobs&lt;/strong&gt;&lt;/h3&gt; 
&lt;p style="color: #181716; background-color: #ffffff;"&gt;In a common scenario where a lot of data for each of our tenants has to be imported, we might be interested in splitting the job into even smaller chunks. &lt;span style="color: #d51313;"&gt;Import is not only about getting metadata from external resources and saving it in to database. The process often contains many smaller steps, such as data validating, fetching additional attachments (documents or images) or transforming to required model data or format in a specific order.&lt;/span&gt; If we have to import images, we generally want to scale them, change the format and perform a few other operations. These seemingly simple operations can consume a lot of resources in our system (and bring headaches to the Site Reliability Engineering (SRE) team if it was performed in the web application serving the requests).&lt;/p&gt; 
&lt;p style="color: #181716; background-color: #ffffff;"&gt;&lt;span style="color: #d51313;"&gt;Thankfully, AWS Batch allows us to split our long process into smaller chunks.&lt;/span&gt; Instead of one long running container performing all the operations, we can process data in multiple, smaller containers with their responsibilities narrowed down. The first container pulls the data into our system, the second one fetches the images and the third rescales them. If rescaling fails at some points, we do not need to redownload the images again – we can simply retry the container with the rescaling part. This also makes the development and testing of such little applications easier.&lt;/p&gt; 
&lt;p style="color: #181716; background-color: #ffffff;"&gt;Using a Batch Array N to N Job, we are able to define a linked-list of dependencies. Job A has to finish first, passing the data to Job B. After that one finishes, Job C is started. The entire process is also an Array Job, so it can be performed for each tenant independently.&lt;/p&gt; 
&lt;p style="color: #181716; background-color: #ffffff;"&gt;Note that it may be tempting to use Step Functions instead and design that kind of workload as follows:&lt;/p&gt; 
&lt;p style="color: #181716; background-color: #ffffff;"&gt;However, there is a subtle difference – if you define it as N to N, then each sequence of jobs runs separately. One of your tenants with a little data can finish the entire sequence quickly, while the others are still at the “Job A” stage. If you use Step Functions instead, all “Job A” tasks must finish before any “Job B” starts. Unless you need it to function that way, you’re often better off with N to N because the workload finishes faster and parallelizes slightly better.&lt;/p&gt; 
&lt;h2 style="color: #181716; background-color: #ffffff;"&gt;Multi-Node Parallel Jobs&lt;/h2&gt; 
&lt;p style="color: #181716; background-color: #ffffff;"&gt;Another interesting capability is &lt;span style="color: #d51313;"&gt;the multi-node parallel job, which allows you to run a single job on multiple EC2 instances&lt;/span&gt;. This differs from a standard job, which occupies only a single EC2 instance. Multi-node jobs are used for large-scale, high-performance computing applications and distributed GPU model training. This is fully compatible with most machine learning frameworks supporting IP-based, internode communication, such as Apache MXNet, TensorFlow, or Caffe2.&lt;/p&gt; 
&lt;p style="color: #181716; background-color: #ffffff;"&gt;If you want to use multi-node parallel jobs on AWS Batch, your application must be prepared to run on multi-node infrastructure, so the code must use frameworks suitable for distributed communication.&lt;/p&gt; 
&lt;p style="color: #181716; background-color: #ffffff;"&gt;Each multi-node parallel job consists of the main node, which is launched at the beginning. After that node is up, the child nodes are launched and started. Forget about compute environments that use Spot Instances, though – multi-node parallel jobs don’t support them. Regardless, you should look into AWS Batch if you’re looking for easy to use and disposable data science compute environments.&lt;/p&gt; 
&lt;h2 style="color: #181716; background-color: #ffffff;"&gt;The quirks we have noticed&lt;/h2&gt; 
&lt;h3 style="color: #181716; background-color: #ffffff; font-weight: normal;"&gt;Batch gives little to no insight from its UI&lt;/h3&gt; 
&lt;p style="color: #181716; background-color: #ffffff;"&gt;Unfortunately, we haven’t been able to extract much information from the UI. If something blows up, you are forced to juggle between Batch, ECS, CloudWatch and Step Functions to find out what exactly happened and why. The community has so far made projects like batchiepatchie to mitigate the issue and provide a different AWS Batch UI. No moves or official plans from AWS, however.&lt;/p&gt; 
&lt;h3 style="color: #181716; background-color: #ffffff; font-weight: normal;"&gt;Batch reacts at a snail’s pace&lt;/h3&gt; 
&lt;p style="color: #181716; background-color: #ffffff;"&gt;You might quickly become annoyed by how slow Batch reacts to events. Everything there seems eventually consistent:&lt;/p&gt; 
&lt;ul style="color: #181716; background-color: #ffffff;"&gt; 
 &lt;li&gt;You schedule a job and you wait until it gets picked up and put in the Job Queue.&lt;br&gt;Then you wait until the Compute Environment notices there are tasks in the Queue – but not enough vCPUs to handle it.&lt;br&gt;Then you wait until it adjusts the desired capacity.&lt;br&gt;Then you wait until Spot Fleet/ASG actually gets the signal to scale up.&lt;br&gt;A few more “then you wait“ moments later… the task is finally running.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p style="color: #181716; background-color: #ffffff;"&gt;Nothing here seems instant – which of course isn’t much of a problem in background long-running tasks, but might be irritating, especially while developing the solution. The feedback loop is unrushed.&lt;/p&gt; 
&lt;h2 style="color: #181716; background-color: #ffffff; font-weight: normal;"&gt;Step Functions are a challenge to debug (and develop)&lt;/h2&gt; 
&lt;p style="color: #181716; background-color: #ffffff;"&gt;Well, the definition of a State Machine is just a horrendous JSON file. When you make a mistake there (or even better – mix it with String interpolation from Terraform), then no IDE will save you. Even the built-in editor in AWS Console fails to provide meaningful error messages. Tests? Forget about it.&lt;/p&gt; 
&lt;p style="color: #181716; background-color: #ffffff;"&gt;Also, no IDE helps you with the input/output processing syntax of SFN. All those $ and .$ take some time to get used to.&lt;/p&gt; 
&lt;p style="color: #181716; background-color: #ffffff;"&gt;A great and useful rant about Step Functions can be &lt;a href="https://www.reddit.com/r/aws/comments/hju8or/does_anyone_else_feel_that_step_functions_have/"&gt;read here&lt;/a&gt; on Reddit – so just know that you’re not alone on this!&lt;/p&gt; 
&lt;h2 style="color: #181716; background-color: #ffffff;"&gt;Launch Configuration of managed Compute Environment with Spot Instances&lt;/h2&gt; 
&lt;p style="color: #181716; background-color: #ffffff;"&gt;There is some magic happening behind the scenes whenever you create Managed Compute Environments with Spot Instances. During creation, you may specify a Launch Template to be used by the EC2s. If Spot Instances are also selected, Batch creates a Spot Fleet Request on your behalf (you have attached AmazonEC2SpotFleetTaggingRole, have you?).&lt;/p&gt; 
&lt;p style="color: #181716; background-color: #ffffff;"&gt;Because Spot Fleet Request requires Launch Templates as well, the one from Compute Environment gets copied. &lt;span style="color: #d51313;"&gt;But then, any changes applied on the Compute Environment’s Launch Template are not propagated to the Spot Fleet Request’s Launch Template.&lt;/span&gt; Our IaC tool of choice (Terraform) was not able to help us there and we spent some time debugging and asking “why doesn’t the cloud-init script change even though the Launch Template does?”.&lt;/p&gt; 
&lt;h2 style="color: #181716; background-color: #ffffff;"&gt;Content-Type of Launch Template&lt;/h2&gt; 
&lt;p style="color: #181716; background-color: #ffffff;"&gt;This &lt;a href="https://docs.aws.amazon.com/batch/latest/userguide/launch-templates.html"&gt;is of course written somewhere in the docs&lt;/a&gt; – make sure any Launch Template is a MIME multi-part file (this is shown just below)!&lt;/p&gt; 
&lt;h2 style="color: #181716; background-color: #ffffff;"&gt;Authentication in a private repository&lt;/h2&gt; 
&lt;p style="color: #181716; background-color: #ffffff;"&gt;ECS is able to pull images from private registries using a handy repositoryCredentials in task definition. Unfortunately, Batch does not support that parameter. If you want to use a protected, private repository you have to ensure the EC2 on which the ECS Agent run has configured ECS_ENGINE_AUTH_DATA. You may either bake that into the AMI or add a script similar to this one in the Launch Template of the Compute Environment. This one pulls credentials from AWS Secrets Manager – make sure your instance will have permission to perform that API call!&lt;/p&gt; 
&lt;p style="color: #181716; background-color: #ffffff;"&gt;&amp;nbsp;&lt;/p&gt; 
&lt;h2 style="color: #181716; background-color: #ffffff;"&gt;&amp;nbsp;&lt;/h2&gt; 
&lt;h2 style="color: #181716; background-color: #ffffff;"&gt;The data engineering struggles&lt;/h2&gt; 
&lt;p style="color: #181716; background-color: #ffffff;"&gt;This is our current go-to template for batch processing and performing background tasks in one of the SaaS projects we maintain and develop.&lt;/p&gt; 
&lt;p style="color: #181716; background-color: #ffffff;"&gt;&lt;strong&gt;Can you (still) do better?&lt;/strong&gt; Well, the real question at this point is &lt;span style="color: #d51313;"&gt;would you use Step Functions as a fully-fledged workflow orchestrator with Batch as an execution engine?&lt;/span&gt; Are they good enough for data engineering projects?&lt;/p&gt; 
&lt;p style="color: #181716; background-color: #ffffff;"&gt;As a starting point, in the MVP phase of an arbitrary project or product – without a doubt. Step Functions are easy to pick up, have enough integrations with other AWS services (like Glue or Batch – very handy in the data world) and work really well in not-so-complicated environments.&lt;strong&gt; &lt;/strong&gt;&lt;span style="color: #d51313;"&gt;Issues arise when connections and dependencies between tasks are no longer not-so-complicated.&lt;/span&gt;&lt;/p&gt; 
&lt;p style="color: #181716; background-color: #ffffff;"&gt;The idea behind Step Functions is a state machine – we observe the current state of the flow and decide what should be done next. Basically, a Step Function is an overcomplicated if/else machine. In data engineering, it is way more convenient to think in Directed Acyclic Graphs (DAGs) – do the first task, then simultaneously those two, combine the results in the next task and so on. Unfortunately, this type of thinking is not supported by SFN and there is no other AWS product which could be used instead.&lt;/p&gt; 
&lt;p style="color: #181716; background-color: #ffffff;"&gt;What about the other types of Batch Jobs we have mentioned? Couldn’t they simulate the DAG? Well, if you can fit into their requirements, they could work for a while. Sooner or later though, your branching logic will get more complicated and Batch will no longer be enough. Fighting with a framework (either SFN or Batch) won’t be easy.&lt;/p&gt; 
&lt;p style="color: #181716; background-color: #ffffff;"&gt;There are also several red flags – when one of your SFN tasks blows up, you can’t just patch it and pick up where you left off. The entire job is marked as a failure and you have to restart the entire graph. This (along with a not-so-pleasant debugging/testing experience and parallelization/branching limits) automatically rules SFN out of data engineering projects, where computations often take hours to complete. There are of course retry mechanisms but they are not enough. We would recommend using Apache Airflow or a similar tool as a DAG scheduler for your data engineering needs. You may run it on AWS EKS, if you wish, and fully integrate with your other AWS tools.&lt;/p&gt; 
&lt;h2 style="color: #181716; background-color: #ffffff;"&gt;The judgement&lt;/h2&gt; 
&lt;p style="color: #181716; background-color: #ffffff;"&gt;&lt;span style="color: #d51313;"&gt;Thankfully, the majority of web applications’ background tasks aren’t that complicated and don’t depend too much on other jobs.&lt;/span&gt; Resizing images, generating sitemaps or reports all can be done independently. In the world of SaaS, they can also be parallelized for each tenant separately. &lt;span style="color: #d51313;"&gt;This makes a great use case for SFN and Batch – as shown above.&lt;/span&gt;&lt;/p&gt; 
&lt;p style="color: #181716; background-color: #ffffff;"&gt;Is it the best solution on the market? Like most things in IT, the answer depends on the scale and requirements of your project. You could use the standard periodic job provided by the framework your web application uses. The implementation will probably be swift, with no interference in the project’s infrastructure.&lt;/p&gt; 
&lt;p style="color: #181716; background-color: #ffffff;"&gt;However, looking at the tradeoffs, this will become dangerous and overload your system, especially if your business model is SaaS. A slight increase in number of tenants would directly “contribute” to the application’s performance and technical debt. The last thing your business needs is an application blowing up because one of your customers has a lot of images to process.&lt;/p&gt; 
&lt;p style="color: #181716; background-color: #ffffff;"&gt;With various AWS technologies already buried deep into the code and the product getting traction, the decision was trivial for us. &lt;span style="color: #d51313;"&gt;The combination of CloudWatch, Step Functions, Batch, Lambda and S3 allows us to process large amounts of data with no impact on our system. If you are in similar place right now, you should definitely give it a shot.&lt;/span&gt;&lt;/p&gt;  
&lt;img src="https://track.hubspot.com/__ptq.gif?a=4709516&amp;amp;k=14&amp;amp;r=https%3A%2F%2Ftech.univio.com%2Fplatforming-saas-application-background-tasks&amp;amp;bu=https%253A%252F%252Ftech.univio.com&amp;amp;bvt=rss" alt="" width="1" height="1" style="min-height:1px!important;width:1px!important;border-width:0!important;margin-top:0!important;margin-bottom:0!important;margin-right:0!important;margin-left:0!important;padding-top:0!important;padding-bottom:0!important;padding-right:0!important;padding-left:0!important; "&gt;</content:encoded>
      <category>Cloud &amp; Infra</category>
      <category>Backend &amp; Data</category>
      <pubDate>Tue, 06 Oct 2020 13:16:50 GMT</pubDate>
      <guid>https://tech.univio.com/platforming-saas-application-background-tasks</guid>
      <dc:date>2020-10-06T13:16:50Z</dc:date>
      <dc:creator>Tomasz Dudek</dc:creator>
    </item>
    <item>
      <title>Quality Assurance vs Quality Control</title>
      <link>https://tech.univio.com/quality-assurance-vs-quality-control</link>
      <description>&lt;div class="hs-featured-image-wrapper"&gt; 
 &lt;a href="https://tech.univio.com/quality-assurance-vs-quality-control?hsLang=en" title="" class="hs-featured-image-link"&gt; &lt;img src="https://tech.univio.com/hubfs/unity_230509_unity_omnichannel_illustration_v3@2x%20(1)-1-1.png" alt="Quality Assurance vs Quality Control" class="hs-featured-image" style="width:auto !important; max-width:50%; float:left; margin:0 15px 15px 0;"&gt; &lt;/a&gt; 
&lt;/div&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;&amp;nbsp;&lt;span style="color: #181716; background-color: #ffffff;"&gt;So much has been written about Quality Assurance that we should ask ourselves if we haven’t lost our understanding of this term. I can’t resist the assumption that each IT project is said to have an elite Quality Assurance unit, composed of software testers only, responsible for ensuring software quality in the project. In addition, HR units only add to this impression when they search for: “QA Specialists”, offering them jobs that focus on reporting tests and reporting defects.&lt;/span&gt;&amp;nbsp;&lt;/p&gt;</description>
      <content:encoded>&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;&amp;nbsp;&lt;span style="color: #181716; background-color: #ffffff;"&gt;So much has been written about Quality Assurance that we should ask ourselves if we haven’t lost our understanding of this term. I can’t resist the assumption that each IT project is said to have an elite Quality Assurance unit, composed of software testers only, responsible for ensuring software quality in the project. In addition, HR units only add to this impression when they search for: “QA Specialists”, offering them jobs that focus on reporting tests and reporting defects.&lt;/span&gt;&amp;nbsp;&lt;/p&gt; 
&lt;h2 style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;&lt;span style="font-weight: normal;"&gt;Differences between the Quality Assurance and Quality Control processes&lt;/span&gt;&lt;strong&gt; &lt;/strong&gt;&lt;/h2&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;What’s the source of these differences? First and foremost, Quality Assurance covers all activities carried out under a project. This starts with cooperation with the client (transparent communication), defining the roles and responsibilities in the team (defining the modus operandi, communication, defining the software development process), and ends with the definition of requirements and their life cycle.&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;The process includes all project participants, giving them the opportunity to influence the shape and definition of quality. This is based on the project’s context and its business value. We should remember about the possibility of measuring and assessing the quality of software at the same time.&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;The QA process is a preventive measure oriented largely toward the entire production process, both in the company and in the project at hand.&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Now, Quality Control focuses largely on the search for errors/ irregularities in the functioning of the application by testing the software at various test levels and using various test types. These are activities that verify and validate the product in terms of compliance with the user’s requirements and expectations. Much of the responsibility lies with the software tester. This is a detective activity.&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;The illustration below shows the proportion between the activities around software testing and the entire quality assurance process.&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;&amp;nbsp;&lt;/p&gt; 
&lt;h2 style="line-height: 1.5; color: #181716; background-color: #ffffff; font-weight: normal;"&gt;&amp;nbsp;&lt;/h2&gt; 
&lt;h2 style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;&lt;span style="font-weight: normal;"&gt;A different look at the Quality Assurance process&lt;/span&gt;&lt;strong&gt; &lt;/strong&gt;&lt;/h2&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;This chart can be used as a “StarterPack” for understanding the Quality Assurance process and the role of the tester. It won’t fit every situation, but it can help you see quality assurance through the prism of increased activity in the project.&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Let’s start from working with requirements. (Find out more about the term &lt;a href="http://itsadeliverything.com/three-amigos-meeting-agree-the-tests-before-development-starts"&gt;“3 Amigos”&lt;/a&gt; here).&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;In the context of software quality, we must bear in mind the beginning of a close cooperation between the 3 Amigos. We have three roles here as presented below:&lt;/p&gt; 
&lt;ol style="line-height: 1.5;"&gt; 
 &lt;li style="list-style-type: none;"&gt; 
  &lt;ol&gt; 
   &lt;li style="line-height: 1.8125; color: #181716; background-color: #ffffff;"&gt; &lt;p&gt;&amp;nbsp;Business analyst –this role may vary from one case to another, but this must surely be a person from the business, e.g. Product Owner.&lt;/p&gt; &lt;/li&gt; 
   &lt;li style="line-height: 1.8125; color: #181716; background-color: #ffffff;"&gt; &lt;p&gt;&amp;nbsp;Programmer.&lt;/p&gt; &lt;/li&gt; 
   &lt;li style="line-height: 1.8125; color: #181716; background-color: #ffffff;"&gt; &lt;p&gt;&amp;nbsp;Software tester.&lt;/p&gt; &lt;/li&gt; 
  &lt;/ol&gt; &lt;/li&gt; 
&lt;/ol&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;In the model described, the three people fulfilling the above functions work together to define the Requirements (Story). This is an important moment when each party presents its point of view and how it understands individual functionalities (a confrontation of visions about the Requirements). A quick feedback loop and mutual understanding appear at this stage. “We don’t talk after implementing the functionality, we talk before that”. Such actions have a major preventive effect on the project and often reveal many risks that haven’t materialized yet, so the cost of their mitigation might be lower.&lt;br&gt;&lt;br&gt;&lt;/p&gt; 
&lt;h2 style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;&lt;span style="font-weight: normal;"&gt;Example questions, e.g. from the perspective of a software tester:&lt;/span&gt;&lt;strong&gt; &lt;/strong&gt;&lt;/h2&gt; 
&lt;ul style="line-height: 1.5;"&gt; 
 &lt;li style="list-style-type: none;"&gt; 
  &lt;ul style="list-style-type: square;"&gt; 
   &lt;li style="line-height: 1.8125; color: #181716; background-color: #ffffff;"&gt; &lt;p&gt;What does the client need this functionality for?&lt;/p&gt; &lt;/li&gt; 
   &lt;li style="line-height: 1.8125; color: #181716; background-color: #ffffff;"&gt; &lt;p&gt;&amp;nbsp;What are the mock-ups, if there are any? &#x1f642;&lt;/p&gt; &lt;/li&gt; 
   &lt;li style="line-height: 1.8125; color: #181716; background-color: #ffffff;"&gt; &lt;p&gt;Does the new requirement affect other components in the application?&lt;/p&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Understandably, each party will have a different set of questions. Consequently, there should be a common understanding as to the product/ value to be delivered.&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Once we know the expected deliverables and outputs, we move smoothly to the stage of implementation of the requirements. At this stage, we can use many methods to improve the software quality, ranging from good practices in relation to design, through to application writing and a set of test-oriented activities:&lt;/p&gt; 
&lt;ul style="line-height: 1.5;"&gt; 
 &lt;li style="list-style-type: none;"&gt; 
  &lt;ul style="list-style-type: square;"&gt; 
   &lt;li style="line-height: 1.8125; color: #181716; background-color: #ffffff;"&gt; &lt;p&gt;unit test coverage of a % of the code,&lt;/p&gt; &lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;An interesting part of this stage of work is the inclusion of &lt;a href="https://martinfowler.com/bliki/TestPyramid.html"&gt;the pyramid of automated tests&lt;/a&gt;, which might slightly influence the shape and scope of our tests.&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;The next steps in the process are the activities that are usually assigned to broadly understood software testers. This is a set of activities related to software verification/ validation, in terms of the above requirements, as well as areas related to quality characteristics (e.g. performance and security).&lt;/p&gt;  
&lt;h2 style="line-height: 1.5; color: #181716; background-color: #ffffff; font-weight: normal;"&gt;What’s next?&lt;/h2&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;Quality Assurance is more than just software testing. Keep that in the back of your head and share this responsibility with the whole team. By inviting and engaging your team members in defining activities around software, make sure that your clients can subscribe to Gucci’s motto: “Quality is remembered long after the price is forgotten”.&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;If you want to learn more about quality management in IT, you should take a look at our &lt;a href="https://www.univio.com/blog/agile-whats-next-starting-a-project-in-the-agile-methodology-part-3/"&gt;publications on agile and software development practices.&lt;/a&gt;&lt;/p&gt; 
&lt;p style="line-height: 1.5; color: #181716; background-color: #ffffff;"&gt;&amp;nbsp;&lt;/p&gt;  
&lt;img src="https://track.hubspot.com/__ptq.gif?a=4709516&amp;amp;k=14&amp;amp;r=https%3A%2F%2Ftech.univio.com%2Fquality-assurance-vs-quality-control&amp;amp;bu=https%253A%252F%252Ftech.univio.com&amp;amp;bvt=rss" alt="" width="1" height="1" style="min-height:1px!important;width:1px!important;border-width:0!important;margin-top:0!important;margin-bottom:0!important;margin-right:0!important;margin-left:0!important;padding-top:0!important;padding-bottom:0!important;padding-right:0!important;padding-left:0!important; "&gt;</content:encoded>
      <category>Quality Control</category>
      <category>Software Quality</category>
      <pubDate>Thu, 14 Feb 2019 13:16:40 GMT</pubDate>
      <guid>https://tech.univio.com/quality-assurance-vs-quality-control</guid>
      <dc:date>2019-02-14T13:16:40Z</dc:date>
      <dc:creator>Tomasz Jański</dc:creator>
    </item>
  </channel>
</rss>
