<?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/"
	>

<channel>
	<title>ShiftMag</title>
	<atom:link href="https://shiftmag.dev/feed/" rel="self" type="application/rss+xml" />
	<link>https://shiftmag.dev/</link>
	<description>Insightful engineering content &#38; community</description>
	<lastBuildDate>Tue, 14 Jul 2026 12:56:20 +0000</lastBuildDate>
	<language>en-GB</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0</generator>

<image>
	<url>https://shiftmag.dev/wp-content/uploads/2024/08/cropped-ShiftMag-favicon-32x32.png</url>
	<title>ShiftMag</title>
	<link>https://shiftmag.dev/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>How Convenient JPA Defaults Broke Our Kotlin Microservice</title>
		<link>https://shiftmag.dev/jpa-defaults-kotlin-microservice-9184/</link>
		
		<dc:creator><![CDATA[Krzysztof Frączek]]></dc:creator>
		<pubDate>Tue, 14 Jul 2026 12:56:20 +0000</pubDate>
				<category><![CDATA[Backend]]></category>
		<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[Case Study]]></category>
		<category><![CDATA[JPA]]></category>
		<category><![CDATA[software architecture]]></category>
		<guid isPermaLink="false">https://shiftmag.dev/?p=9184</guid>

					<description><![CDATA[<p>The promise of JPA is simple: define your entities, let the framework handle the rest. And it works until you look at what "the rest" means. </p>
<p>The post <a href="https://shiftmag.dev/jpa-defaults-kotlin-microservice-9184/">How Convenient JPA Defaults Broke Our Kotlin Microservice</a> appeared first on <a href="https://shiftmag.dev">ShiftMag</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">While testing a <strong>Kotlin microservice backed by MS SQL</strong>, I found several places where <strong>convenience had quietly become a liability</strong>. </p>



<p class="wp-block-paragraph">Fortunately, there was no production incident; most issues were detected during internal testing. It is always better to learn on someone else&#8217;s mistakes, this article will help you learn on mine.</p>



<h2 class="wp-block-heading"><span id="the-architecture-in-place">The architecture in place</span></h2>



<p class="wp-block-paragraph">The service orchestrates WhatsApp campaign delivery through an asynchronous, scheduler-driven pipeline. Campaign destinations enter the system via an API and are persisted to MS SQL Server. Two background schedulers handle the processing. The first retrieves unscored destinations, invokes a scoring service to evaluate delivery priority, and assigns each destination to a bulk: either appending to an existing one or creating a new bulk when capacity is reached.</p>



<p class="wp-block-paragraph">The second scheduler manages the delivery lifecycle: it polls the external Bulk Scheduling System for status updates, submits ready bulks for sending, and coordinates priority by pausing lower-scored bulks while higher-priority ones are in flight. MS SQL serves as the central state store, maintaining campaign metadata, bulk assignments, and processing status throughout the pipeline.</p>



<figure class="wp-block-image size-large"><img fetchpriority="high" decoding="async" width="1024" height="614" src="https://shiftmag.dev/wp-content/uploads/2026/04/Simic-Shiftmag-5-1024x614.png?x94846" alt="" class="wp-image-9186" srcset="https://shiftmag.dev/wp-content/uploads/2026/04/Simic-Shiftmag-5-1024x614.png 1024w, https://shiftmag.dev/wp-content/uploads/2026/04/Simic-Shiftmag-5-300x180.png 300w, https://shiftmag.dev/wp-content/uploads/2026/04/Simic-Shiftmag-5-768x461.png 768w, https://shiftmag.dev/wp-content/uploads/2026/04/Simic-Shiftmag-5.png 1200w" sizes="(max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">An illustration of how the two schedulers interact with the MS SQL Server</figcaption></figure>



<h2 class="wp-block-heading"><span id="insert-record-in-batches">Insert record in batches</span></h2>



<p class="wp-block-paragraph">When you expect a heavy load,&nbsp;<strong>don&#8217;t insert data one by one</strong>. We learned this when a client started sending their campaign as separate HTTP requests—one message per request, all belonging to the same campaign. Our controller accepted a list of messages, but a single-element list is still a list, right? The service started returning HTTP 500 errors due to waiting too long for an available database connection.</p>



<p class="wp-block-paragraph">We solved this by introducing&nbsp;<strong>Kafka as a buffer between the API and the database</strong>. Incoming requests get published to a topic and then consumed in batches, enabling batch inserts into the database. A nice bonus came from how Kafka handles partitioning: by setting the message key properly, we ensured that&nbsp;<strong>all requests for the same campaign land in the same partition</strong>—and get processed together.</p>



<p class="wp-block-paragraph">Of course, the implementation should still handle lists properly. One caveat: Hibernate does support batch inserts (feel free to&nbsp;<a rel="noreferrer noopener" href="https://www.baeldung.com/jpa-hibernate-batch-insert-update" target="_blank">check</a>), but not when you use an IDENTITY primary key generation strategy. With IDENTITY, the database generates the ID on each insert.</p>



<p class="wp-block-paragraph">To get true batching, we bypassed Hibernate and used plain JDBC.</p>



<pre class="wp-block-code"><code>override fun submitCampaign(campaignRequest: CampaignRequest) {
    val message = campaignRequest.messages&#91;0].message
    val campaignId = campaignRequest.parameters.campaignId ?: "no-campaign-id"
    val topicKey = "${message.channelId}-${message.from}" +
                   "-${campaignRequest.parameters.templateName}-$campaignId"
    val messageBatches = campaignRequest.messages.chunked(maxMessagesPerBatch)

    messageBatches.forEach { batch -&gt;
        val batchRequest = CampaignRequest(
            messages = batch,
            parameters = campaignRequest.parameters
        )
        campaignRequestProducer.send(ProducerRecord(TOPIC_NAME, topicKey, batchRequest))
    }
}

@KafkaListener(
    topics = &#91;TOPIC_NAME],
    containerFactory = KafkaConsumerConfiguration.BATCH_LISTENER_FACTORY_BEAN
)
@Timed
fun processRequests(
    records: List&lt;ConsumerRecord&lt;String, CampaignRequest&gt;&gt;,
    ack: Acknowledgment
) {
    val groupedByCampaign = records.groupBy { it.key() }

    for ((_, recordsGroup) in groupedByCampaign) {
        val campaign = findOrCreateCampaign(...)
        val destinations = recordsGroup.flatMap { it.value().messages }.mapToDestinations(campaign)
        storeCampaignDestinations(destinations)
    }

    ack.acknowledge()
}

@Transactional
override fun batchInsert(destinations: List&lt;CampaignDestination&gt;) {
    if (destinations.isEmpty()) return

    val sql = """
        INSERT INTO cds.campaign_destination
            (campaign_id, destination, external_message_id, content, failover)
        VALUES
            (?, ?, ?, ?, ?)
    """.trimIndent()

    jdbcTemplate.batchUpdate(sql, destinations, destinations.size) { ps, dest -&gt;
        ps.setLong(1, dest.campaign.id)
        ps.setString(2, dest.destination)
        ps.setString(3, dest.externalMessageId)
        ps.setString(4, dest.content)
        ps.setString(5, dest.failover)
    }
}
</code></pre>



<p class="wp-block-paragraph">Now Kafka took the big chunk of stress, the database can easily handle the load.</p>



<figure class="wp-block-image size-full"><img decoding="async" width="753" height="263" src="https://shiftmag.dev/wp-content/uploads/2026/04/image-2026-1-27_10-44-18.png?x94846" alt="" class="wp-image-9188" srcset="https://shiftmag.dev/wp-content/uploads/2026/04/image-2026-1-27_10-44-18.png 753w, https://shiftmag.dev/wp-content/uploads/2026/04/image-2026-1-27_10-44-18-300x105.png 300w" sizes="(max-width: 753px) 100vw, 753px" /></figure>



<figure class="wp-block-image size-full is-resized"><img decoding="async" width="502" height="202" src="https://shiftmag.dev/wp-content/uploads/2026/04/image-2026-1-27_10-44-57.png?x94846" alt="" class="wp-image-9187" style="width:754px;height:auto" srcset="https://shiftmag.dev/wp-content/uploads/2026/04/image-2026-1-27_10-44-57.png 502w, https://shiftmag.dev/wp-content/uploads/2026/04/image-2026-1-27_10-44-57-300x121.png 300w" sizes="(max-width: 502px) 100vw, 502px" /></figure>



<h2 class="wp-block-heading"><span id="too-complex-queries">Too complex queries</span></h2>



<p class="wp-block-paragraph">A query that&#8217;s too complex can take too long to execute, especially without proper indexes. Think about&nbsp;<strong>what data you already have in the application</strong>&nbsp;and use it to simplify things. In our case, we needed to find bulks that still had space for more recipients. The original query joined the destinations table to count how many each bulk contained, filtered by several conditions, and used a HAVING clause to check capacity.</p>



<pre class="wp-block-code"><code>@Query("""
    SELECT cb, COUNT(cd) FROM CampaignBulk cb
    LEFT JOIN CampaignDestination cd ON cd.campaignBulk = cb
    WHERE cb.campaign = :campaign AND cb.priority IN (:priorities) AND cb.waitUntil &gt; :nowWithBuffer AND cb.bulkStatus = 'CREATED'
    GROUP BY cb
    HAVING COUNT(cd) &lt; :maxBulkSize
""")
fun findNotFullAndNotExpiredBulks(campaign: Campaign, priorities: Set&lt;BulkPriority&gt;, maxBulkSize: Int, nowWithBuffer: Instant): List&lt;BulkWithCount&gt;
</code></pre>



<p class="wp-block-paragraph">The problem? A join on an unindexed column, filters without indexes, a COUNT, and a HAVING clause. Combined, it was too much for the database. The query took ages and locks escalated to entire tables. It quickly turned out that we already knew the destination count during processing. So we denormalized: we added a&nbsp;<strong><code>destinationCount</code>&nbsp;column to the&nbsp;<code>CampaignBulk</code>&nbsp;table</strong> and updated it whenever destinations were added. The new query and supporting index look like this:</p>



<pre class="wp-block-code"><code>@Query("""
    SELECT cb FROM CampaignBulk cb
    WHERE cb.campaign = :campaign
      AND cb.priority IN (:priorities)
      AND cb.waitUntil &gt; :nowWithBuffer
      AND cb.bulkStatus = 'CREATED'
      AND cb.destinationCount &lt; :maxBulkSize
""")
fun findNotFullAndNotExpiredBulks(
    campaign: Campaign,
    priorities: Set&lt;BulkPriority&gt;,
    maxBulkSize: Int,
    nowWithBuffer: Instant
): List&lt;CampaignBulk&gt;
</code></pre>



<pre class="wp-block-code"><code>CREATE NONCLUSTERED INDEX idx_campaign_bulk_count_filter
ON cds.campaign_bulk(campaign_id, bulk_status, destination_count)
INCLUDE (id, priority, wait_until, bss_bulk_id, api_key_id, creation_date, last_status_change_date);
</code></pre>



<p class="wp-block-paragraph">After these changes, the query performs well.</p>



<figure class="wp-block-image size-full is-resized"><img loading="lazy" decoding="async" width="500" height="199" src="https://shiftmag.dev/wp-content/uploads/2026/04/image-2026-1-27_11-10-40.png?x94846" alt="" class="wp-image-9190" style="width:814px;height:auto" srcset="https://shiftmag.dev/wp-content/uploads/2026/04/image-2026-1-27_11-10-40.png 500w, https://shiftmag.dev/wp-content/uploads/2026/04/image-2026-1-27_11-10-40-300x119.png 300w" sizes="auto, (max-width: 500px) 100vw, 500px" /></figure>



<h2 class="wp-block-heading">Concurrency: when more isn&#8217;t always better</h2>



<p class="wp-block-paragraph">We all want to process data as fast as possible. Especially in the world of virtual threads; you can spin up thousands of them and feel good about how concurrent your application is. But the&nbsp;<strong>database doesn&#8217;t share that enthusiasm</strong>. Under the hood, you have a limited Hikari connection pool. Run too many concurrent operations and your queries start timing out. Worse, when multiple threads hit the same table and the same dataset, you&#8217;re heading straight for lock contention.</p>



<p class="wp-block-paragraph">Here are a few things to consider when you need to control concurrency.</p>



<h2 class="wp-block-heading"><span id="use-shedlock"><strong>Use shedlock</strong></span></h2>



<p class="wp-block-paragraph">ShedLock is a library that ensures scheduled tasks run only once across multiple application instances. It works by creating a lock record in a shared storage—typically a database table—before executing a task. When a scheduler triggers, it tries to acquire the lock by inserting or updating a row. If another instance already holds the lock, the<strong> task is skipped.</strong></p>



<p class="wp-block-paragraph">The lock is released after execution or after a configured timeout, preventing deadlocks if an instance crashes mid-task. In our case, we wanted to avoid the same campaign being processed by a couple of instances at the same time.</p>



<p class="wp-block-paragraph">Shedlock helps a lot here. Feel free to check the&nbsp;<a rel="noreferrer noopener" href="https://github.com/lukas-krecan/ShedLock" target="_blank">full ShedLock documentation</a>.</p>



<pre class="wp-block-code"><code>val config = LockConfiguration(
    Instant.now(),
    LOCK_NAME_FOR_PROCESS_CAMPAIGNS + campaign.id,
    Duration.ofMinutes(5),
    Duration.ZERO
)

val lock = lockProvider.lock(config)

if (lock.isPresent) {
    try {
        singleCampaignService.processSingleCampaign(campaign)
    } finally {
        lock.get().unlock()
    }
}
</code></pre>



<p class="wp-block-paragraph"><strong>Limit your concurrency with a semaphore</strong></p>



<p class="wp-block-paragraph">A <strong>Semaphore</strong> lets you limit how many threads can execute a block of code at the same time. In our case, each scheduler iteration could potentially process dozens of campaigns in parallel; especially with virtual threads, where spawning new threads is cheap. But each campaign processing involves multiple database operations: reads, updates, and inserts. Letting all of them run at once would exhaust the connection pool and trigger lock contention.</p>



<p class="wp-block-paragraph">We introduced a Semaphore with a fixed number of permits to cap the number of campaigns processed concurrently. Before processing a campaign, a&nbsp;<strong>thread must acquire a permit</strong>. If all permits are taken, the thread waits, but with virtual threads, this isn&#8217;t a problem.</p>



<p class="wp-block-paragraph">When a virtual thread blocks, it gets unmounted from its carrier thread, freeing it to run other virtual threads. So waiting for a permit doesn&#8217;t waste OS resources like it would with traditional platform threads. Once processing is done, the permit is released.</p>



<p class="wp-block-paragraph">This keeps database load predictable and prevents the connection pool from becoming a bottleneck.</p>



<pre class="wp-block-code"><code>private val semaphore = Semaphore(10)
private val executor = Executors.newVirtualThreadPerTaskExecutor()

fun processCampaigns() {
    val campaigns = campaignRepository.findAllToProcess()

    campaigns.forEach { campaign -&gt;
        executor.submit {
            semaphore.acquire()
            try {
                processSingleCampaign(campaign)
            } finally {
                semaphore.release()
            }
        }
    }
}
</code></pre>



<p class="wp-block-paragraph"><strong>Use query hints</strong></p>



<p class="wp-block-paragraph">When multiple threads query the same table, the database decides how to handle locking. Sometimes those defaults work against you in different ways. Locks escalate, threads wait on each other, or worse, deadlocks occur. SQL Server lets you guide this behavior with query hints. Here are the ones we found useful:</p>



<ul class="wp-block-list">
<li><code>UPDLOCK</code>&nbsp;– reserves update locks on selected rows, so other threads can&#8217;t select the same rows for processing.</li>



<li><code>READPAST</code>&nbsp;– skips rows that are already locked by other threads instead of waiting for them to be released.</li>



<li><code>ROWLOCK</code>&nbsp;– suggests that SQL Server use fine-grained row-level locks instead of page or table locks.</li>



<li><code>NOLOCK</code>&nbsp;– reads rows without acquiring shared locks, allowing it to read data that other transactions are currently modifying. This means it won&#8217;t block writers and won&#8217;t be blocked by them but it can return dirty data that might be rolled back, or even read the same row twice or skip rows entirely if data is being moved during the scan.</li>
</ul>



<p class="wp-block-paragraph"><strong>Think about your access patterns</strong>. Are multiple threads competing for the same rows? Are you okay with skipping locked data or reading uncommitted changes? The right combination of hints depends on your specific use case but knowing they exist can save you from mysterious slowdowns and deadlocks.</p>



<p class="wp-block-paragraph"><strong>Process data in batches</strong></p>



<p class="wp-block-paragraph">Even with ROWLOCK hints,&nbsp;<strong>SQL Server can escalate locks</strong>. When a single transaction acquires too many row locks on one table, SQL Server may convert them into a table lock for efficiency. This is called lock escalation, and when it happens, your &#8220;harmless&#8221; operation suddenly blocks everyone else.</p>



<p class="wp-block-paragraph">We learned this the hard way. Our scoring scheduler fetched all unscored destinations for a campaign in a single query, which sometimes includes tens of thousands of rows. With UPDLOCK to prevent other threads from picking them up, SQL Server decided it was cheaper to lock the entire table. Suddenly, other threads couldn&#8217;t read or write to the destinations table at all. The whole pipeline stalled, waiting for one greedy query to finish.</p>



<p class="wp-block-paragraph">The fix was simple: fetch in batches. Instead of selecting all unscored destinations, we now use&nbsp;<code>TOP(n)</code>&nbsp;and iterate until there&#8217;s nothing left to process.</p>



<pre class="wp-block-code"><code>SELECT TOP(400) cd.*
FROM cds.campaign_destination cd WITH (UPDLOCK, READPAST, ROWLOCK)
WHERE cd.campaign_id = :campaignId
  AND cd.bulk_id IS NULL
  AND cd.id &lt;= :maxId
</code></pre>



<p class="wp-block-paragraph">Each batch locks only a few hundred rows, commits, and moves on. This keeps the lock count well below the escalation threshold and lets other threads continue their work.</p>



<p class="wp-block-paragraph">For more details on lock escalation, see&nbsp;<a rel="noreferrer noopener" href="https://learn.microsoft.com/en-us/troubleshoot/sql/database-engine/performance/resolve-blocking-problems-caused-lock-escalation" target="_blank">Microsoft&#8217;s Troubleshooting explanation.</a></p>



<h2 class="wp-block-heading"><span id="final-thoughts">Final thoughts</span></h2>



<p class="wp-block-paragraph">The database is not an implementation detail you can ignore. I hope these lessons save you some debugging time. </p>



<p class="wp-block-paragraph">Have you faced similar challenges? I&#8217;m curious how others handle these problems.</p>


<figure class="wp-block-post-featured-image"><img loading="lazy" decoding="async" width="1200" height="630" src="https://shiftmag.dev/wp-content/uploads/2026/06/JPA.png?x94846" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="jpa header for shiftmag" style="object-fit:cover;" srcset="https://shiftmag.dev/wp-content/uploads/2026/06/JPA.png 1200w, https://shiftmag.dev/wp-content/uploads/2026/06/JPA-300x158.png 300w, https://shiftmag.dev/wp-content/uploads/2026/06/JPA-1024x538.png 1024w, https://shiftmag.dev/wp-content/uploads/2026/06/JPA-768x403.png 768w" sizes="auto, (max-width: 1200px) 100vw, 1200px" /></figure><p>The post <a href="https://shiftmag.dev/jpa-defaults-kotlin-microservice-9184/">How Convenient JPA Defaults Broke Our Kotlin Microservice</a> appeared first on <a href="https://shiftmag.dev">ShiftMag</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Developers are the reason behind best (and worst) parts of software development</title>
		<link>https://shiftmag.dev/developers-are-the-reason-behind-best-and-worst-parts-of-software-development-10670/</link>
		
		<dc:creator><![CDATA[Ivan Simic]]></dc:creator>
		<pubDate>Mon, 13 Jul 2026 13:53:00 +0000</pubDate>
				<category><![CDATA[Career]]></category>
		<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[Developers Answer]]></category>
		<category><![CDATA[Engineer Explains]]></category>
		<category><![CDATA[software engineering]]></category>
		<guid isPermaLink="false">https://shiftmag.dev/?p=10670</guid>

					<description><![CDATA[<p>Building software is full of ups and downs. Some days, you're working with the best team you can find, and others it's up to you to fix something with no idea how it works and no access to documentation.</p>
<p>The post <a href="https://shiftmag.dev/developers-are-the-reason-behind-best-and-worst-parts-of-software-development-10670/">Developers are the reason behind best (and worst) parts of software development</a> appeared first on <a href="https://shiftmag.dev">ShiftMag</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">In the latest edition of our <a href="https://www.youtube.com/@DevelopersAnswer" target="_blank" rel="noreferrer noopener">Developers Answer series</a>, we spoke with developers about their <strong>best and worst projects</strong>, the reasons behind the challenges, and the ways they&#8217;ve made it across the finish line regardless of the hardships.</p>



<h2 class="wp-block-heading">What&#8217;s the worst type of project?</h2>



<p class="wp-block-paragraph">Sure, the term &#8220;worst&#8221; means different things to different people, but most of the engineers agree: the worst types of projects are the ones that <strong>aren&#8217;t set up well by humans,</strong> not the ones that have big technical requirements. And, as you can probably guess, human-designed flaws are much more creative.</p>



<p class="wp-block-paragraph">For example, one engineer highlighted that the worst project for him was working with family members who were not familiar with software development at all, affecting expectations, realisations and everything in between.</p>



<p class="wp-block-paragraph">Another situation was a client project that took four months, with progress going smooth up until the last month. <strong>Nikola Buhiniček,</strong> Engineering Manager, said:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="has-medium-font-size wp-block-paragraph">The client changed the scope significantly without much warning. We had to abandon a lot of the work we’d already done and come up with new features and opportunities. It felt like compressing two and a half months of work into one month before the deadline.</p>
</blockquote>



<p class="wp-block-paragraph">Another type of projects that drive engineers crazy are legacy code projects without real instructions on how to approach them, as explained by<strong> Edvin Teskeredžić</strong>, Senior AI Software Engineer:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="has-medium-font-size wp-block-paragraph">We had this old legacy project, basically 10-year-old code which needed to be maintained. It was also all internal libraries but there was no documentation. The documentation simply lived in the heads of senior engineers, so you had to kind of figure it out yourself, and you couldn&#8217;t Google it because it was all internal libraries.</p>
</blockquote>



<h2 class="wp-block-heading">What&#8217;s the best, then?</h2>



<p class="wp-block-paragraph">In contrast, the best projects tend to be tied to others as well, only this time it&#8217;s about great teams and good colleagues. For some engineers, the best projects are those where leadership has a clear vision and that vision is clearly shown to the teams.</p>



<p class="wp-block-paragraph">Other engineeers, such as <strong>Filip Bolčić</strong>, Full-Stack Engineer, highlighted <strong>teamwork as the best part of the projects</strong> they&#8217;ve worked on. For example:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="has-medium-font-size wp-block-paragraph">Everybody&#8217;s insight was really valuable, and I had a great mentor from whom I learned a lot. It was just a really meaningful project for us, we felt really good working on it.</p>
</blockquote>



<p class="wp-block-paragraph">On the other hand, Nikola noted that sometimes, <strong>the best projects are the most challenging ones</strong>. He explained the process of adding the automations feature to Productive was one of the more challenging and interesting ones he worked on:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="has-medium-font-size wp-block-paragraph">It was such a different feature from what we used to do, and I was given the opportunity to build it. In the end it was one of the best features we have. The usage is growing up from month to month. I&#8217;m really happy that it was something that I built like two years ago, and it&#8217;s still growing so fast.</p>
</blockquote>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="20 Developers Share Their Best and Worst Projects" width="500" height="281" src="https://www.youtube.com/embed/kyjc9KEN6L4?start=165&amp;feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>



<h2 class="wp-block-heading"><span id="it-all-comes-down-to-the-human-factor">It all comes down to the human factor</span></h2>



<p class="wp-block-paragraph">The hardest thing to fix as an engineer might not even be software-related, according to <strong>Hrvoje Rančić, </strong>Senior Software Engineer:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="has-medium-font-size wp-block-paragraph">My posture. I had really terrible back pain from sitting too much during the COVID era. I think this is a very dangerous job because it involves a lot of sitting, and sitting is the new smoking, so I encourage everyone to move more if you&#8217;re a software engineer.</p>
</blockquote>



<p class="wp-block-paragraph">Ergonomics aside, Software Engineer <strong>Emin Mulaimović </strong>said that some of the biggest recent challenges he had were related to LLM&#8217;s:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="has-medium-font-size wp-block-paragraph">We had this unstable LLM prompt which basically means you ask the same question and it gives different answers, and the answers are not marginally different. To fix that you just need to rephrase the question over and over and over again until it worked. And then when it worked you didn&#8217;t learn anything, you didn&#8217;t have fun fixing it, you&#8217;re just glad it&#8217;s over. Some bugs are fun to fix; this one wasn&#8217;t.</p>
</blockquote>



<p class="wp-block-paragraph">On the other end of the spectrum, the toughness of a task comes down to a <strong>personal mistake by the engineer themselves</strong>, and there&#8217;s rarely anything you can do but to fix it. That&#8217;s exactly what happened to Filip:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="has-medium-font-size wp-block-paragraph">I remember working on a really big-scale production application and accidentally just deleting a lot of important stuff from the database. I was really young in my career and I remember being really stressed out about this, but the project manager protected me and we were able to restore a backup of this database, so in the end everything was good, but it was really stressful for me.</p>
</blockquote>



<p class="wp-block-paragraph">And to further drive the point home, sometimes the fix isn&#8217;t even tough, but so time-consuming you think you&#8217;re going crazy, as evidenced by <strong>Olga Koroleva</strong>, Engineering Manager:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="has-medium-font-size wp-block-paragraph">I made a bug in the code where entries to the database were written wrong, and I had to manually fix thousands of them. After that, I always double-checked and triple-checked everything.</p>
</blockquote>



<p class="wp-block-paragraph">Make sure to <a href="https://www.youtube.com/watch?v=kyjc9KEN6L4&amp;t=165s" target="_blank" rel="noreferrer noopener">check out the entirety of the video</a> to find more about the best and worst projects, and the challenges of software development!</p>



<p class="wp-block-paragraph"><em>Special thanks to our engineering colleagues at Infobip, Nikola Buhiniček (Engineering Manager, Productive) and Filip Bolčić, (Full-Stack Engineer, Ars Futura).</em></p>


<figure class="wp-block-post-featured-image"><img loading="lazy" decoding="async" width="1365" height="768" src="https://shiftmag.dev/wp-content/uploads/2026/07/devs-answer-best-and-worst.png?x94846" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="" style="object-fit:cover;" srcset="https://shiftmag.dev/wp-content/uploads/2026/07/devs-answer-best-and-worst.png 1365w, https://shiftmag.dev/wp-content/uploads/2026/07/devs-answer-best-and-worst-300x169.png 300w, https://shiftmag.dev/wp-content/uploads/2026/07/devs-answer-best-and-worst-1024x576.png 1024w, https://shiftmag.dev/wp-content/uploads/2026/07/devs-answer-best-and-worst-768x432.png 768w" sizes="auto, (max-width: 1365px) 100vw, 1365px" /></figure><p>The post <a href="https://shiftmag.dev/developers-are-the-reason-behind-best-and-worst-parts-of-software-development-10670/">Developers are the reason behind best (and worst) parts of software development</a> appeared first on <a href="https://shiftmag.dev">ShiftMag</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>AI Helps Ship Faster, But It Doesn’t Do the Thinking</title>
		<link>https://shiftmag.dev/ai-helps-ship-faster-but-it-doesnt-do-the-thinking-10555/</link>
		
		<dc:creator><![CDATA[Marko Crnjanski]]></dc:creator>
		<pubDate>Wed, 08 Jul 2026 13:33:35 +0000</pubDate>
				<category><![CDATA[Artificial Intelligence]]></category>
		<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[AI coding]]></category>
		<category><![CDATA[code review]]></category>
		<category><![CDATA[developer tools]]></category>
		<category><![CDATA[software development]]></category>
		<category><![CDATA[technical debt]]></category>
		<category><![CDATA[vibe coding]]></category>
		<guid isPermaLink="false">https://shiftmag.dev/?p=10555</guid>

					<description><![CDATA[<p>We asked engineers how far AI can really go in software delivery, and their answer was simple: it can speed things up, but people still have to make the decisions.</p>
<p>The post <a href="https://shiftmag.dev/ai-helps-ship-faster-but-it-doesnt-do-the-thinking-10555/">AI Helps Ship Faster, But It Doesn’t Do the Thinking</a> appeared first on <a href="https://shiftmag.dev">ShiftMag</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">AI coding assistants have made it look dangerously easy to believe software can now be built by prompt alone. </p>



<p class="wp-block-paragraph">In a recent conversation with a few Infobip engineers, we asked whether that promise holds up in practice &#8211; and the answer was clear: <strong>AI can generate code fast, but it still cannot understand the problem</strong>, define the boundaries, or own the consequences. </p>



<p class="wp-block-paragraph">That part remains the developer’s job.</p>



<h2 class="wp-block-heading"><span id="ai-should-be-a-tool-for-accelerating-clearly-defined-tasks">AI should be a tool for accelerating clearly defined tasks</span></h2>



<p class="wp-block-paragraph">Better context and clearer specifications make useful, maintainable, and secure output far more likely. As <strong>Zvonimir Petković</strong>, Staff Engineer, explained:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">The quality of the code ultimately depends on the context given to the GenAI agent and the model underneath. The software engineer is still the one writing the specifications, and the better the specification and context, the better the code produced.</p>
</blockquote>



<p class="wp-block-paragraph">To maintain quality, he says, we need to isolate the code into smaller segments and check each one. Effective work with coding agents is <strong>less about one large prompt and more about small, controlled iterations</strong>.</p>



<p class="wp-block-paragraph">That may mean changing the architecture, refactoring a component, or requesting a more precise implementation of a single interface. <strong>František Lučivjanský</strong>, Senior Principal Engineer, described a similar workflow:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">I work with AI in smaller chunks. I give it a small part, review the result, and steer the agent: &#8220;This is not correct; do it this way.&#8221; I may also define the architecture differently &#8211; for example, by asking it to refactor one part first. These slow iterations help me maintain the same quality I would achieve manually.</p>
</blockquote>



<p class="wp-block-paragraph">Working in smaller chunks helps developers preserve a mental model of the system and review decisions while the code is still easy to change. AI serves as a tool for accelerating clearly defined tasks.</p>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="Why Great AI Code Still Needs Real Engineering" width="500" height="281" src="https://www.youtube.com/embed/wxWxsWqxZvI?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>



<h2 class="wp-block-heading">AI doesn&#8217;t create technical debt, people do</h2>



<p class="wp-block-paragraph">Faster code generation naturally raises questions about technical debt. Teams have more code to understand, test, and maintain, but AI did not create technical debt. <strong>Debt grows from deadlines, trade-offs, and decisions that prioritize short-term delivery over long-term maintainability</strong>.</p>



<p class="wp-block-paragraph">For <strong>Tvrtko Ivasić</strong>, Application Security Intern, the answer is not to relax established controls, but to reinforce them:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">We should preserve the standards established in the past: the security pillars, the SDLC pipeline, code review, SAST, and the rest of the process. If anything, the bar should be even higher because the code is now generated by AI rather than written by an engineer.</p>
</blockquote>



<p class="wp-block-paragraph">AI-generated code should go through the same SDLC as human-written code: code review, automated tests, SAST, and dependency checks. </p>



<p class="wp-block-paragraph">František Lučivjanský notes that agents don’t remove the pressures behind technical debt, but <strong>they can help manage it more deliberately</strong>. They can also spot duplication, suggest refactors, write tests, or explain legacy code, but the value still depends on the engineer reviewing the output.</p>



<h2 class="wp-block-heading"><span id="vibe-coding-might-evolve-into-agent-engineering">Vibe coding might evolve into agent engineering</span></h2>



<p class="wp-block-paragraph">Vibe coding may be enough for a hobby project or proof of concept, but problems begin when the same workflow reaches production without additional controls. Engineers may not need to write or memorize every line, but they still <strong>need to understand the architecture, system boundaries, scalability, and failure modes</strong>, enough to delegate implementation without delegating responsibility.</p>



<p class="wp-block-paragraph">Asked whether vibe coding is a sustainable approach to software development or merely a short-term productivity boost, Zvonimir argued that it is likely to evolve:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">Vibe coding is not just a short-term boost or a passing trend. &#8220;Dark factories&#8221; may represent the ultimate direction, with workflows that incorporate vibe coding and require us to look at the code less and less. I think it will evolve into agent engineering, and that is how software will be built in the future.</p>
</blockquote>



<p class="wp-block-paragraph">Companies that adopt this workflow may ship faster without sacrificing quality, spending less time on routine code and more on specifications, architecture, evaluation, and automated controls. The key is to understand where vibe coding creates speed, where it introduces risk, and how AI agents fit into proven software engineering principles &#8211; because <strong>responsibility for what reaches production remains unchanged</strong>.</p>



<p class="wp-block-paragraph"><em>Special thanks to our engineering colleagues from <a href="https://www.infobip.com/" target="_blank" rel="noreferrer noopener">Infobip</a>, the publisher of ShiftMag!</em></p>


<figure class="wp-block-post-featured-image"><img loading="lazy" decoding="async" width="1280" height="720" src="https://shiftmag.dev/wp-content/uploads/2026/06/2_2.jpg?x94846" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="" style="object-fit:cover;" srcset="https://shiftmag.dev/wp-content/uploads/2026/06/2_2.jpg 1280w, https://shiftmag.dev/wp-content/uploads/2026/06/2_2-300x169.jpg 300w, https://shiftmag.dev/wp-content/uploads/2026/06/2_2-1024x576.jpg 1024w, https://shiftmag.dev/wp-content/uploads/2026/06/2_2-768x432.jpg 768w" sizes="auto, (max-width: 1280px) 100vw, 1280px" /></figure><p>The post <a href="https://shiftmag.dev/ai-helps-ship-faster-but-it-doesnt-do-the-thinking-10555/">AI Helps Ship Faster, But It Doesn’t Do the Thinking</a> appeared first on <a href="https://shiftmag.dev">ShiftMag</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Doist CEO: &#8216;The bar to create has dropped, but the quality bar has risen&#8217;</title>
		<link>https://shiftmag.dev/doist-ceo-the-bar-to-create-has-dropped-but-the-quality-bar-has-risen-10479/</link>
		
		<dc:creator><![CDATA[Ivan Simic]]></dc:creator>
		<pubDate>Tue, 07 Jul 2026 14:25:15 +0000</pubDate>
				<category><![CDATA[Business of Software]]></category>
		<category><![CDATA[Productivity]]></category>
		<category><![CDATA[amir sahefendic]]></category>
		<category><![CDATA[doist]]></category>
		<category><![CDATA[Infobip Shift 2026]]></category>
		<category><![CDATA[todoist]]></category>
		<guid isPermaLink="false">https://shiftmag.dev/?p=10479</guid>

					<description><![CDATA[<p>Amir Sahefendic, CEO and founder of Doist, says success now depends on solving real problems and building products people actually want to keep using.</p>
<p>The post <a href="https://shiftmag.dev/doist-ceo-the-bar-to-create-has-dropped-but-the-quality-bar-has-risen-10479/">Doist CEO: &#8216;The bar to create has dropped, but the quality bar has risen&#8217;</a> appeared first on <a href="https://shiftmag.dev">ShiftMag</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">More work means more tasks, and more tasks requires better organizing. But <strong>building a company that lasts in a competitive market</strong> is far harder. Amir Sahefinendic did just that with Doist &#8211; the company behind the task management tool Todoist and async communication tool Twist.</p>



<p class="wp-block-paragraph">Ahead of the <a href="https://shift.infobip.com/?%7CEU%7C-Shift_Zadar_2024-%5BTy:G_Brand_Search;Lng:EN;Bid:MAN_eCPC%5D" target="_blank" rel="noreferrer noopener">Infobip Shift Conference</a> in Zadar this September (for which you get a <a href="https://www.entrio.hr/en/event/infobip-shift-2026-27033?pc=MAG15" target="_blank" rel="noreferrer noopener">special discount as a ShiftMag reader</a>), we spoke with Amir, who will be one of the speakers. Reflecting on Doist’s longevity, he said, “We’ve always thought in decades, not quarters.”</p>



<p class="wp-block-paragraph">While many Todoist competitors raised big funding rounds and grew too fast before being acquired or shutting down, Doist chose a <strong>slower, steadier path focused on product and users</strong> &#8211; and it paid off.</p>



<h2 class="wp-block-heading"><span id="remote-work-needs-to-be-sustainable-not-glamorous">Remote work needs to be sustainable, not glamorous</span></h2>



<p class="wp-block-paragraph">Doist has also been remote-first from the start and is often cited as an <strong>early example of remote work at scale</strong>.</p>



<p class="wp-block-paragraph">They have spoken often about job satisfaction, mental health and wellbeing, but he says Doist hasn’t “solved” mental health in remote work. Instead, the company is structured to make people less likely to feel isolated or overworked, or to struggle quietly.</p>



<p class="wp-block-paragraph">Furthermore, Amir explained:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">Remote work offers freedom, but it can also blur boundaries and create loneliness. So we focus on making it sustainable, not on making it glamorous. We’re remote-first, not nomad-first: people can work from anywhere, but we encourage them to build roots near friends, family, and community.</p>
</blockquote>



<p class="wp-block-paragraph">For Amir, <strong>people simply do their best work when they have good lives</strong>. Simple as it may be, it&#8217;s also something that goes completely over the heads of many companies, especially fast-growing startups in the &#8220;AI hustle&#8221; era.</p>



<h2 class="wp-block-heading"><span id="building-software-isn%e2%80%99t-enough-anymore">Building software isn’t enough anymore</span></h2>



<p class="wp-block-paragraph">A quick Google or LinkedIn search tells you all you need to know about the state of productivity apps  and software in 2026. The marketplaces are flooded with AI tools and wrapper apps, creating a <strong>greater need for quick success </strong>than just a few years before, and a “closing window” dynamic where developers must achieve massive scale in months or <a href="https://www.loot-drop.io/deep-dive/ai" target="_blank" rel="noreferrer noopener">disappear</a>.</p>



<p class="wp-block-paragraph">Amir tells us that, despite this, many of the fundamentals still matter:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">Are you solving a real customer pain point in a 10x way? Is your solution differentiated? Do you have strong marketing and a memorable brand?</p>
</blockquote>



<p class="wp-block-paragraph">Continuing, Amir says that the bar to create has dropped dramatically, but the quality bar has risen just as much. To succeed now, one needs to build something far better than what was required when Amir was starting out. Concluding, Amir says that you &#8220;need to be incredible at many things, such as design, marketing and sales, not just software.&#8221;</p>



<h2 class="wp-block-heading"><span id="engineering-still-matters-in-2026">Engineering still matters in 2026</span></h2>



<p class="wp-block-paragraph">Doist emphasizes <strong>deliberate decision-making</strong>, and that same approach shapes its engineering culture. For Amir, “engineering culture at Doist” means:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">Making clear technical choices and trade-offs that help us serve users, move faster with confidence, and build durable foundations. It’s about thoughtful preparation, strong ownership, high-quality systems, and focusing on the technical work that matters most (not chasing everything at once).</p>
</blockquote>



<p class="wp-block-paragraph">Speaking of engineering, Amir&#8217;s talk at <a href="https://shift.infobip.com/?%7CEU%7C-Shift_Zadar_2024-%5BTy:G_Brand_Search;Lng:EN;Bid:MAN_eCPC%5D" target="_blank" rel="noreferrer noopener">Infobip Shift</a> will be watched by engineers and leaders in the space, many of whom are building products themselves. To them, he says that the <strong>engineering mindset is still incredibly useful for building and scaling companies</strong>, and that engineering still matters a lot in 2026.</p>



<p class="wp-block-paragraph"><strong>Make sure to reserve your ticket with a <a href="https://www.entrio.hr/en/event/infobip-shift-2026-27033?pc=MAG15" target="_blank" rel="noreferrer noopener">special discount for ShiftMag readers</a>!</strong></p>


<figure class="wp-block-post-featured-image"><img loading="lazy" decoding="async" width="1200" height="630" src="https://shiftmag.dev/wp-content/uploads/2026/06/amir-doist-shiftmag.png?x94846" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="" style="object-fit:cover;" srcset="https://shiftmag.dev/wp-content/uploads/2026/06/amir-doist-shiftmag.png 1200w, https://shiftmag.dev/wp-content/uploads/2026/06/amir-doist-shiftmag-300x158.png 300w, https://shiftmag.dev/wp-content/uploads/2026/06/amir-doist-shiftmag-1024x538.png 1024w, https://shiftmag.dev/wp-content/uploads/2026/06/amir-doist-shiftmag-768x403.png 768w" sizes="auto, (max-width: 1200px) 100vw, 1200px" /></figure>


<p class="wp-block-paragraph"></p>
<p>The post <a href="https://shiftmag.dev/doist-ceo-the-bar-to-create-has-dropped-but-the-quality-bar-has-risen-10479/">Doist CEO: &#8216;The bar to create has dropped, but the quality bar has risen&#8217;</a> appeared first on <a href="https://shiftmag.dev">ShiftMag</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Google Careeer Ladder for Engineers Explained</title>
		<link>https://shiftmag.dev/google-career-ladder-explained-for-engineers-10368/</link>
		
		<dc:creator><![CDATA[Anastasija Uspenski]]></dc:creator>
		<pubDate>Mon, 06 Jul 2026 13:04:04 +0000</pubDate>
				<category><![CDATA[Career]]></category>
		<category><![CDATA[career ladder]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Google Creer Dreamer]]></category>
		<guid isPermaLink="false">https://shiftmag.dev/?p=10368</guid>

					<description><![CDATA[<p>This article provides a detailed overview of Google’s career structure, from the entry - level L3, up to elite titles like Google Fellow - L10.</p>
<p>The post <a href="https://shiftmag.dev/google-career-ladder-explained-for-engineers-10368/">Google Careeer Ladder for Engineers Explained</a> appeared first on <a href="https://shiftmag.dev">ShiftMag</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">“I work at Google” is a statement that carries prestige. It signals that someone operates in a strong engineering environment at a stable company, with a clear career structure and the opportunity <strong>to build products used by millions of people worldwid</strong>e.</p>



<p class="wp-block-paragraph">But what does that career structure actually look like?</p>



<p class="wp-block-paragraph">To answer that, we explored publicly available discussions on platforms like Reddit and Dev.to, connected common patterns, and compiled <strong>a clear overview of the Google engineering ladder</strong>.</p>



<h2 class="wp-block-heading"><span id="what-the-google-engineering-ladder-looks-like">What the Google engineering ladder looks like</span></h2>



<p class="wp-block-paragraph">Public sources generally describe Google’s engineering levels like this:</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>Level</th><th>Role</th><th>General Interpretation</th></tr></thead><tbody><tr><td>L3</td><td>Software Engineer II</td><td>Entry-level engineer</td></tr><tr><td>L4</td><td>Software Engineer III</td><td>Mid-level engineer</td></tr><tr><td>L5</td><td>Senior Software Engineer</td><td>Senior engineer</td></tr><tr><td>L6</td><td>Staff Software Engineer</td><td>Staff level</td></tr><tr><td>L7</td><td>Senior Staff Software Engineer</td><td>Senior Staff level</td></tr><tr><td>L8</td><td>Principal Engineer</td><td>Principal level</td></tr><tr><td>L9</td><td>Distinguished Engineer</td><td>Extremely high technical level</td></tr><tr><td>L10</td><td>Google Fellow</td><td>Elite and very rare level</td></tr><tr><td>L11</td><td>Senior Google Fellow</td><td>Highest IC level</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">At the early stages, engineers typically focus on learning, delivering well-scoped tasks, and becoming independent in familiar problem spaces. In contrast, at higher levels, the emphasis <strong>shifts toward technical strategy, cross-team collaboration, and creating impact that extends far beyond individual contributions</strong>.</p>



<h2 class="wp-block-heading"><span id="google-rewards-increased-scope-greater-leverage-and-sustained-impact-over-time">Google rewards increased scope, greater leverage, and sustained impact over time</span></h2>



<p class="wp-block-paragraph">A common misconception is that more years of experience automatically lead to higher levels. However, reality is more nuanced. Instead, Google evaluates engineers based on scope, impact, and influence.</p>



<p class="wp-block-paragraph"><strong>At lower levels</strong>, engineers are expected to:</p>



<ul class="wp-block-list">
<li>Learn systems quickly and effectively</li>



<li>Deliver tasks with appropriate guidance</li>



<li>Collaborate closely with teammates</li>



<li>Build strong technical independence over time</li>
</ul>



<p class="wp-block-paragraph">As engineers progress to <strong>mid-level roles</strong>, expectations expand. They are expected to:</p>



<ul class="wp-block-list">
<li>Lead complex projects from start to finish</li>



<li>Make sound technical decisions under uncertainty</li>



<li>Navigate ambiguous requirements</li>



<li>Take ownership of systems or features</li>



<li>Communicate effectively across teams and functions</li>
</ul>



<p class="wp-block-paragraph">Meanwhile, <strong>at higher levels</strong>, the focus shifts again. Engineers are expected to:</p>



<ul class="wp-block-list">
<li>Influence multiple teams and stakeholders</li>



<li>Understand organizational and technical context broadly</li>



<li>Define or shape technical direction</li>



<li>Solve systemic rather than isolated problems</li>



<li>Multiply impact through others</li>



<li>Act as anchors for large-scale initiatives</li>
</ul>



<h2 class="wp-block-heading"><span id="senior-vs-staff">Senior vs. staff</span></h2>



<p class="wp-block-paragraph">The transition from Senior to Staff is often considered one of the most significant jumps in the entire ladder.</p>



<p class="wp-block-paragraph"><strong>A Senior Engineer typically</strong>:</p>



<ul class="wp-block-list">
<li>Works independently on complex problems</li>



<li>Leads major features or components</li>



<li>Understands architecture and trade-offs</li>



<li>Mentors other engineers</li>



<li>Delivers impact primarily within a single team or domain</li>
</ul>



<p class="wp-block-paragraph">Senior Engineer is a strong individual contributor whose influence remains largely within a defined area.</p>



<p class="wp-block-paragraph">However, a Staff Engineer operates differently.</p>



<p class="wp-block-paragraph"><strong>A Staff Engineer</strong>:</p>



<ul class="wp-block-list">
<li>Focuses on the broader system, not just one team</li>



<li>Connects multiple teams and initiatives</li>



<li>Identifies and resolves systemic issues</li>



<li>Drives cross-organizational projects</li>



<li>Aligns people, processes, and architecture</li>



<li>Produces impact that extends beyond direct output</li>
</ul>



<p class="wp-block-paragraph">Therefore, the shift is not about doing more work. Instead, it is about expanding influence and creating long-term, scalable impact across systems and teams.</p>



<h2 class="wp-block-heading"><span id="outcomes-matter-more-than-job-titles">Outcomes matter more than job titles</span></h2>


<figure class="wp-block-post-featured-image"><img loading="lazy" decoding="async" width="1200" height="630" src="https://shiftmag.dev/wp-content/uploads/2026/06/Google.Careers.png?x94846" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="" style="object-fit:cover;" srcset="https://shiftmag.dev/wp-content/uploads/2026/06/Google.Careers.png 1200w, https://shiftmag.dev/wp-content/uploads/2026/06/Google.Careers-300x158.png 300w, https://shiftmag.dev/wp-content/uploads/2026/06/Google.Careers-1024x538.png 1024w, https://shiftmag.dev/wp-content/uploads/2026/06/Google.Careers-768x403.png 768w" sizes="auto, (max-width: 1200px) 100vw, 1200px" /></figure>


<p class="wp-block-paragraph">Google’s leveling decisions are usually shaped by three major factors.</p>



<h3 class="wp-block-heading"><span id="1-interview-performance">1. Interview Performance</span></h3>



<p class="wp-block-paragraph">During interviews, candidates are evaluated on:</p>



<ul class="wp-block-list">
<li>Technical depth</li>



<li>Problem-solving ability</li>



<li>Analytical thinking</li>



<li>Role-specific knowledge</li>



<li>Leadership signals</li>
</ul>



<p class="wp-block-paragraph">However, strong coding skills alone are not enough. Candidates must demonstrate they can think like engineers who design and maintain large-scale systems.</p>



<h3 class="wp-block-heading"><span id="2-previous-experience-and-projects">2. Previous Experience and Projects</span></h3>



<p class="wp-block-paragraph">Experience matters, but it is not the only factor.</p>



<p class="wp-block-paragraph">More importantly, Google looks at:</p>



<ul class="wp-block-list">
<li>What you actually delivered</li>



<li>The impact of your work</li>



<li>The complexity of your projects</li>



<li>Whether you led meaningful initiatives</li>



<li>Evidence of ownership and responsibility</li>
</ul>



<h3 class="wp-block-heading"><span id="3-skill-set-and-ability-to-create-impact">3. Skill Set and Ability to Create Impact</span></h3>



<p class="wp-block-paragraph">In addition, Google values engineers who can:</p>



<ul class="wp-block-list">
<li>Learn quickly in new environments</li>



<li>Make informed risk assessments</li>



<li>Operate effectively under ambiguity</li>



<li>Communicate clearly and consistently</li>



<li>Influence others through credibility and mentorship</li>



<li>Take responsibility beyond formal assignments</li>
</ul>



<p class="wp-block-paragraph">As a result, seniority reflects not only technical ability but also influence and leadership without authority.</p>



<h2 class="wp-block-heading"><span id="how-much-do-google-engineers-earn">How much do Google engineers earn?</span></h2>



<p class="wp-block-paragraph">Based on public reports, approximate annual compensation ranges often look like this:</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>Level</th><th>Role</th><th>Approx. Annual Compensation</th></tr></thead><tbody><tr><td>L3</td><td>Junior Software Engineer</td><td>~$132,190</td></tr><tr><td>L4</td><td>Software Engineer III</td><td>~$158,399</td></tr><tr><td>L5</td><td>Senior Software Engineer</td><td>~$188,284</td></tr><tr><td>L6</td><td>Staff Software Engineer</td><td>~$232,219</td></tr><tr><td>L7</td><td>Senior Staff Software Engineer</td><td>~$266,100</td></tr><tr><td>L8</td><td>Principal Engineer</td><td>~$273,700</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">For L9 and above, public data is limited, and discussions tend to focus more on rarity and impact than exact numbers.</p>



<h2 class="wp-block-heading"><span id="overall-compensation-depends-on-several-factors">Overall compensation depends on several factors</span></h2>



<p class="wp-block-paragraph">It is important to remember that these figures are estimates based on public sources, not official salary disclosures. Actual compensation varies depending on:</p>



<ul class="wp-block-list">
<li>Location</li>



<li>Level</li>



<li>Base salary</li>



<li>Bonuses</li>



<li>Equity (stock grants)</li>



<li>Performance</li>



<li>Team and product area</li>
</ul>



<p class="wp-block-paragraph">For this reason, professionals in Big Tech usually refer to total compensation (TC) rather than base salary alone.</p>



<h2 class="wp-block-heading"><span id="what-is-above-l6">What is above L6?</span></h2>



<p class="wp-block-paragraph">As engineers advance beyond Staff level, their responsibilities become increasingly strategic.</p>



<h3 class="wp-block-heading"><span id="l7-senior-staff">L7: Senior Staff</span></h3>



<p class="wp-block-paragraph">At this stage, engineers influence multiple teams and broader domains. Rather than solving isolated problems, they help shape how entire groups of teams operate.</p>



<h3 class="wp-block-heading"><span id="l8-principal-engineer">L8: Principal Engineer</span></h3>



<p class="wp-block-paragraph">Principal Engineers define technical direction across large areas of the organization. This role requires long-term thinking, strong systems design skills, and the ability to align complex technical decisions.</p>



<h3 class="wp-block-heading"><span id="l9-distinguished-engineer-fellow-senior-fellow">L9+: Distinguished Engineer, Fellow, Senior Fellow</span></h3>



<p class="wp-block-paragraph">Only a very small number of engineers reach these levels. Their influence can extend across:</p>



<ul class="wp-block-list">
<li>Entire organizations</li>



<li>The company as a whole</li>



<li>The broader tech industry</li>
</ul>



<p class="wp-block-paragraph">At this stage, the focus shifts from implementation to shaping the future direction of large-scale systems and platforms.</p>



<h2 class="wp-block-heading"><span id="what-is-google-career-dreamer">What is Google Career Dreamer?</span></h2>



<p class="wp-block-paragraph"><a href="https://grow.google/career-dreamer/home/?srsltid=AfmBOoqDBjxtBumYRYhBHyOpjBu1y9NtWWEtzdShwmAyAlm-XUgL7U6F" type="link" id="https://grow.google/career-dreamer/home/?srsltid=AfmBOoqDBjxtBumYRYhBHyOpjBu1y9NtWWEtzdShwmAyAlm-XUgL7U6F" target="_blank" rel="noreferrer noopener">Google Career Dreamer</a> is a career exploration and guidance tool designed to help users better understand their skills and career options.</p>



<p class="wp-block-paragraph">It helps users:</p>



<ul class="wp-block-list">
<li>Identify transferable skills</li>



<li>Define their professional identity</li>



<li>Explore potential career paths</li>



<li>Prepare for career transitions</li>
</ul>



<h3 class="wp-block-heading"><span id="main-features">Main Features</span></h3>



<p class="wp-block-paragraph"><strong>1. Career Identity Statement</strong><br>This feature helps users summarize their professional profile for use in resumes, LinkedIn, portfolios, and introductions.</p>



<p class="wp-block-paragraph"><strong>2. Explore Career Possibilities</strong><br>It suggests roles aligned with a user’s experience and skills.</p>



<p class="wp-block-paragraph"><strong>3. Relevant Jobs Near You</strong><br>Users can discover job opportunities that match both profile and location.</p>



<p class="wp-block-paragraph"><strong>4. Gemini Support</strong><br>The tool also integrates AI support for:</p>



<ul class="wp-block-list">
<li>Cover letters</li>



<li>Resume improvements</li>



<li>Career planning</li>
</ul>



<p class="wp-block-paragraph">In conclusion, the Google career ladder is not defined by a single dimension but by the scale of problems you solve, your influence across teams, your ability to handle ambiguity, your leadership without authority, and the multiplier effect of your work.</p>



<p class="wp-block-paragraph"></p>
<p>The post <a href="https://shiftmag.dev/google-career-ladder-explained-for-engineers-10368/">Google Careeer Ladder for Engineers Explained</a> appeared first on <a href="https://shiftmag.dev">ShiftMag</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Human Decisions Are The Real Bottleneck Of Agent Design</title>
		<link>https://shiftmag.dev/human-decisions-are-the-real-bottleneck-of-agent-design-10364/</link>
		
		<dc:creator><![CDATA[Joanna Suau]]></dc:creator>
		<pubDate>Thu, 02 Jul 2026 13:06:41 +0000</pubDate>
				<category><![CDATA[Artificial Intelligence]]></category>
		<category><![CDATA[agentic AI]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[infobip]]></category>
		<category><![CDATA[LLM]]></category>
		<category><![CDATA[MCP]]></category>
		<guid isPermaLink="false">https://shiftmag.dev/?p=10364</guid>

					<description><![CDATA[<p>Anyone who’s clicked "always allow" on an agent knows the outcome: broad permissions, minimal oversight, and results that are correct on paper but strange in practice. </p>
<p>The post <a href="https://shiftmag.dev/human-decisions-are-the-real-bottleneck-of-agent-design-10364/">Human Decisions Are The Real Bottleneck Of Agent Design</a> appeared first on <a href="https://shiftmag.dev">ShiftMag</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">For that reason, the safer pattern, which is minimal permissions and human approval required, is becoming the default. This means <strong>agents are increasingly making decisions that require a human response before anything happens next</strong>. </p>



<p class="wp-block-paragraph">The question is how that response gets requested. </p>



<p class="wp-block-paragraph">The agent ran. It checked the queue, detected the anomaly, made the call. Then it produced a tidy summary (decision, rationale,&nbsp;confidence&nbsp;score) and delivered it to the person who was watching.&nbsp;</p>



<p class="wp-block-paragraph">That&#8217;s&nbsp;the happy path. The fact of the matter is that<strong> most runs&nbsp;aren&#8217;t&nbsp;that clean.&nbsp;&nbsp;</strong></p>



<h2 class="wp-block-heading"><span id="one-failure-a-dozen-scenarios">One failure, a dozen scenarios</span></h2>



<p class="wp-block-paragraph">Each of the cases listed below is a version of the same failure: the agent did its job, but the result&nbsp;didn&#8217;t&nbsp;reach the right person:</p>



<ul class="wp-block-list">
<li>The agent hit a step it&nbsp;couldn&#8217;t&nbsp;resolve and stopped, waiting for an approval that nobody saw.&nbsp;&nbsp;</li>



<li>A decision came back ambiguous and needed&nbsp;a human call, but there was no way to surface that to the right person in time.&nbsp;&nbsp;</li>



<li>An edge case surfaced mid-run that the original prompt&nbsp;didn&#8217;t&nbsp;account for, and the agent had no way to escalate it. By the time anyone noticed, the context was stale.&nbsp;</li>



<li>The colleague who needs to act on the decision&nbsp;wasn&#8217;t&nbsp;in the thread. The on-call engineer&nbsp;isn&#8217;t&nbsp;watching the terminal.&nbsp;&nbsp;</li>



<li>The&nbsp;automated pipeline&nbsp;that ran at 3am had no audience.&nbsp;&nbsp;</li>
</ul>



<p class="wp-block-paragraph">The agent&#8217;s output is readable, but&nbsp;it&#8217;s&nbsp;trapped in the interface that produced it: visible to&nbsp;whoever happened to be present, <strong>invisible</strong> <strong>to</strong> <strong>everyone</strong> <strong>else</strong>.&nbsp;</p>



<p class="wp-block-paragraph">Connecting the agent to a messaging channel&nbsp;doesn&#8217;t&nbsp;solve the problem entirely, but it does extend the reach of its output beyond&nbsp;the&nbsp;interface&nbsp;it ran in.&nbsp;&nbsp;</p>



<h2 class="wp-block-heading"><span id="tool-count-is-an-architectural-decision">Tool count is an architectural decision&nbsp;</span></h2>



<p class="wp-block-paragraph">The practical question is how&nbsp;to do it properly. Most messaging&nbsp;MCP&nbsp;servers are built for full-featured channel integrations: scheduling, logs, template&nbsp;management, bulk sending.&nbsp;That&#8217;s&nbsp;useful if you need it. But for an agent that just needs to notify someone or request a human decision,&nbsp;you&#8217;re&nbsp;loading a lot of tools into the model&#8217;s context that have nothing to do with the task.&nbsp;</p>



<p class="wp-block-paragraph"><strong>Every tool you expose to an&nbsp;LLM costs&nbsp;more than the API rate card suggests. </strong>The tool&#8217;s schema,&nbsp;name, description, parameters,&nbsp;gets&nbsp;injected into the model&#8217;s context on every invocation. A server with 27 tools loads 27 definitions into every request. The model&nbsp;them has to&nbsp;reason over all of them.&nbsp;</p>



<p class="wp-block-paragraph">That&#8217;s&nbsp;not always a problem. If your agent needs scheduling, delivery logs, carrier-level capability checks, or template management, a&nbsp;full-featured channel server earns its footprint, and&nbsp;it’s&nbsp;typically the most common go-to use case for messaging MCP servers.&nbsp;</p>



<p class="wp-block-paragraph">But if the agent just needs to notify someone,&nbsp;you&#8217;re&nbsp;paying a <strong>context tax on 26 tools&nbsp;you&nbsp;didn&#8217;t&nbsp;ask for.&nbsp;</strong></p>



<p class="wp-block-paragraph">This is the argument behind deliberately minimal MCP servers: for simple use cases, smaller is also more&nbsp;accurate, not just cheaper.&nbsp;&nbsp;</p>



<h2 class="wp-block-heading">What &#8220;minimal&#8221;&nbsp;could&nbsp;look like in practice&nbsp;</h2>



<p class="wp-block-paragraph">When Infobip talked to developers using its MCP ecosystem, a pattern&nbsp;emerged: some of them&nbsp;weren&#8217;t&nbsp;reaching for the full feature set. They had a pipeline, an agent, and a need to notify someone (sometimes to attach a screenshot while at it). </p>



<p class="wp-block-paragraph">The&nbsp;Infobip&nbsp;<a href="https://github.com/infobip/mcp" target="_blank" rel="noreferrer noopener">Message MCP&nbsp;server</a>&nbsp;is a direct response to that feedback: one or two tools covering SMS, RCS, and Viber, with support for images where the channel allows&nbsp;for&nbsp;it.&nbsp;&nbsp;</p>



<p class="wp-block-paragraph">There&#8217;s&nbsp;something worth noting in that design choice. The broader Infobip MCP ecosystem includes channel-specific servers with rich&nbsp;feature sets: the RCS server has 27 tools, WhatsApp has 18. The Message server sits deliberately at the opposite end&nbsp;and caters to use cases that only require&nbsp;low footprint.&nbsp;&nbsp;</p>



<p class="wp-block-paragraph">It’s&nbsp;not a replacement for the channel-specific servers, but a different tool for a different job.&nbsp;The agent can then s<strong>end a notification across&nbsp;three different&nbsp;channels</strong> from a single tool call.&nbsp;</p>



<h2 class="wp-block-heading"><span id="the-pattern%c2%a0behind-the-product%c2%a0">The pattern behind the product </span></h2>



<p class="wp-block-paragraph">Out of this integration comes an <strong>interesting trade-off </strong>to consider: how does the minimal-footprint pattern hold up as agents get more capable? </p>



<p class="wp-block-paragraph">Agents take on more complex workflows.&nbsp;The instinct is to give them more tools, more context,&nbsp;more capability,&nbsp;and&nbsp;more surface area. But&nbsp;since&nbsp;the relationship between tool count and agent performance is not linear, past a certain point, more tools&nbsp;will always&nbsp;mean more ambiguity about what&nbsp;to call, more opportunity for hallucinated parameters, more tokens spent on reasoning over options rather than executing.&nbsp;</p>



<p class="wp-block-paragraph">For narrow, high-frequency actions (notifications and alerts being the clearest example), there&#8217;s a real case for purpose-built tools that do one thing and declare that scope clearly. <strong>Not every agent capability needs the full API surface</strong>. </p>



<p class="wp-block-paragraph">Whether that principle scales to more complex tasks, and whether the industry converges on a layered tool architecture rather than a flat&nbsp;one, is still an open question.&nbsp;&nbsp;</p>



<p class="wp-block-paragraph">But for&nbsp;now, for&nbsp;the specific problem of &#8220;my agent needs to reach a human,&#8221; starting minimal and adding surface&nbsp;area only when the use case demands&nbsp;it&nbsp;seems like&nbsp;a&nbsp;more defensible approach.&nbsp;&nbsp;&nbsp;</p>


<figure class="wp-block-post-featured-image"><img loading="lazy" decoding="async" width="1200" height="630" src="https://shiftmag.dev/wp-content/uploads/2026/07/New-ShiftMag-panel-interview-3.png?x94846" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="" style="object-fit:cover;" srcset="https://shiftmag.dev/wp-content/uploads/2026/07/New-ShiftMag-panel-interview-3.png 1200w, https://shiftmag.dev/wp-content/uploads/2026/07/New-ShiftMag-panel-interview-3-300x158.png 300w, https://shiftmag.dev/wp-content/uploads/2026/07/New-ShiftMag-panel-interview-3-1024x538.png 1024w, https://shiftmag.dev/wp-content/uploads/2026/07/New-ShiftMag-panel-interview-3-768x403.png 768w" sizes="auto, (max-width: 1200px) 100vw, 1200px" /></figure><p>The post <a href="https://shiftmag.dev/human-decisions-are-the-real-bottleneck-of-agent-design-10364/">Human Decisions Are The Real Bottleneck Of Agent Design</a> appeared first on <a href="https://shiftmag.dev">ShiftMag</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Why Good Architecture Still Fails in Production</title>
		<link>https://shiftmag.dev/why-good-architecture-still-fails-in-production-9894/</link>
		
		<dc:creator><![CDATA[Ivan Pelivanovic]]></dc:creator>
		<pubDate>Tue, 30 Jun 2026 12:52:02 +0000</pubDate>
				<category><![CDATA[Backend]]></category>
		<category><![CDATA[Engineering Management]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[Devoxx]]></category>
		<category><![CDATA[software architecture]]></category>
		<guid isPermaLink="false">https://shiftmag.dev/?p=9894</guid>

					<description><![CDATA[<p>At Devoxx UK in London, I caught up with Eoin Woods - co-author of three software architecture books and former CTO of Endava, to find out why beautifully designed systems still break in production.</p>
<p>The post <a href="https://shiftmag.dev/why-good-architecture-still-fails-in-production-9894/">Why Good Architecture Still Fails in Production</a> appeared first on <a href="https://shiftmag.dev">ShiftMag</a>.</p>
]]></description>
										<content:encoded><![CDATA[<figure class="wp-block-post-featured-image"><img loading="lazy" decoding="async" width="2100" height="1400" src="https://shiftmag.dev/wp-content/uploads/2026/05/Eoin-devoxx-2-1-scaled.jpg?x94846" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="" style="object-fit:cover;" srcset="https://shiftmag.dev/wp-content/uploads/2026/05/Eoin-devoxx-2-1-scaled.jpg 2100w, https://shiftmag.dev/wp-content/uploads/2026/05/Eoin-devoxx-2-1-300x200.jpg 300w, https://shiftmag.dev/wp-content/uploads/2026/05/Eoin-devoxx-2-1-1024x683.jpg 1024w, https://shiftmag.dev/wp-content/uploads/2026/05/Eoin-devoxx-2-1-768x512.jpg 768w" sizes="auto, (max-width: 2100px) 100vw, 2100px" /></figure>


<p class="wp-block-paragraph">Eoin, who now works independently across software architecture, green software, and engineering, <strong>has spent decades around large systems</strong>. </p>



<p class="wp-block-paragraph">The failures he keeps seeing are rarely exotic. They begin with something mundane, an environmental detail nobody verified, a technology nobody fully understood, or a second order effect nobody expected until the system was already live.</p>



<p class="wp-block-paragraph">That is why, for him, architecture is less about drawing clean systems on paper and more about <strong>surfacing the assumptions production will eventually expose</strong>.</p>



<h2 class="wp-block-heading"><span id="production-is-where-the-assumptions-become-visible">Production is where the assumptions become visible</span></h2>



<p class="wp-block-paragraph">When I asked Eoin where failures come from, he resisted the temptation to separate elegant design from messy execution. He argued, the system that matters is the one that ships, and the one that ships is full of assumptions.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">Ultimately the problem is always the design or actually, not even the design but what ends up in production&#8230;</p>
</blockquote>



<p class="wp-block-paragraph">This means that diagram may look reasonable, the architecture review may pass and the slide deck may even sound convincing. Production is where the assumptions become visible. <strong>Experience changes what people notice</strong>, Eoin put this bluntly:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">The older and more cynical you get, the more questions you ask.</p>
</blockquote>



<p class="wp-block-paragraph">Seniority, at least in architecture, often means <strong>noticing the missing question</strong> before the missing answer turns into an incident. The same logic applies to coupled systems. A component can behave well on its own and still create trouble once the rest of the system starts reacting to it.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="683" src="https://shiftmag.dev/wp-content/uploads/2026/06/Eoin-devoxx-1-1024x683.jpg?x94846" alt="" class="wp-image-10205" srcset="https://shiftmag.dev/wp-content/uploads/2026/06/Eoin-devoxx-1-1024x683.jpg 1024w, https://shiftmag.dev/wp-content/uploads/2026/06/Eoin-devoxx-1-300x200.jpg 300w, https://shiftmag.dev/wp-content/uploads/2026/06/Eoin-devoxx-1-768x512.jpg 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">Photo: Marin Pavelić</figcaption></figure>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">If one component slows down dramatically, the others (if tightly bound to it) probably slow down dramatically as well. It’s only when it actually happens that everyone realises everything else slows down in lockstep, because they hadn’t realised how coupled together they were.</p>
</blockquote>



<p class="wp-block-paragraph">That is the kind of failure teams usually understand only after the fact. The system behaves as designed, then fails as a whole because the interactions were never really understood as interactions.</p>



<h2 class="wp-block-heading"><span id="architecture-is-never-just-about-structure">Architecture is never just about structure</span></h2>



<p class="wp-block-paragraph">That distinction matters most where recovery is expensive. Financial infrastructure, healthcare, industrial control, and similar environments do not get the luxury of treating failure as a learning exercise.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">We’re much less enthusiastic about moving fast, breaking things and fixing forwards actually because if we do break something in a mission critical system it has a really serious side effect.</p>
</blockquote>



<p class="wp-block-paragraph">In those environments, <strong>speed only helps when recovery is cheap</strong>. If rollback is hard, repair is slow, or the impact is irreversible, then fast delivery stops being a virtue and starts becoming a liability.</p>



<p class="wp-block-paragraph">That is why architecture is never just about structure, but about consequences. A design that looks efficient in a presentation can become expensive in the real world the moment its assumptions meet a system that cannot absorb mistakes.</p>



<h2 class="wp-block-heading"><span id="writing-the-scenario-forces-the-hidden-question-into-the-open">Writing the scenario forces the hidden question into the open</span></h2>



<p class="wp-block-paragraph">Eoin made the same argument in his Devoxx talk by describing a scene almost every engineer will recognise. </p>



<p class="wp-block-paragraph">A stakeholder asks for something scalable, cost effective, secure, and easy to use. The architect comes back with containerised microservices, lower storage costs, forced password changes, and a task oriented interface. The stakeholder says it sounds good, while still not really understanding what was asked or what was decided.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="683" src="https://shiftmag.dev/wp-content/uploads/2026/06/55258320547_374de78c6f_o-1024x683.jpg?x94846" alt="" class="wp-image-10203" srcset="https://shiftmag.dev/wp-content/uploads/2026/06/55258320547_374de78c6f_o-1024x683.jpg 1024w, https://shiftmag.dev/wp-content/uploads/2026/06/55258320547_374de78c6f_o-300x200.jpg 300w, https://shiftmag.dev/wp-content/uploads/2026/06/55258320547_374de78c6f_o-768x512.jpg 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">Photo: Devoxx / Flickr</figcaption></figure>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">That gap between what was asked and what was understood is exactly what architectural scenarios are designed to close.</p>
</blockquote>



<p class="wp-block-paragraph">A scenario takes a vague wish and turns it into something concrete. Not &#8220;the system should be scalable&#8221; but what happens when 5,000 users connect at the same time and the primary database fails at 7pm during peak load. Not &#8220;the app should be secure&#8221; but what happens when a decryption key needs to be recovered after an incident. The value of that exercise is not subtle.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">There’s nothing like writing a scenario to reveal what you don’t know about your own system.</p>
</blockquote>



<p class="wp-block-paragraph">That is why scenarios matter, Eoin believes. They do not make uncertainty disappear, but they do force it into view.</p>



<p class="wp-block-paragraph">He described six practical uses for scenarios. Teams use them to:</p>



<ul class="wp-block-list">
<li>decide what to build</li>



<li>compare design options</li>



<li>drive research</li>



<li>assess design choices more broadly</li>



<li>explain existing system behaviour to people who need to understand it without getting lost in technical detail</li>



<li>surface the questions that should have been asked much earlier</li>
</ul>



<p class="wp-block-paragraph">The point is not documentation for its own sake though, but to <strong>make the system legible</strong> before production does the explanation instead.</p>



<p class="wp-block-paragraph">If offline mode has only been demonstrated and never truly tested against the live system, the scenario is where that becomes obvious. If a recovery flow exists mainly in a vendor demo, the scenario turns the demo into a question rather than a conclusion.</p>



<h2 class="wp-block-heading"><span id="the-simplest-useful-habit-is-still-discipline">The simplest useful habit is still discipline</span></h2>



<p class="wp-block-paragraph">Eoin’s most practical advice was also the least glamorous: </p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">Make architectural decisions intentionally, and write them down.</p>
</blockquote>



<p class="wp-block-paragraph">This means <strong>recording the assumptions built into it, the trade offs it accepts, and the implications that follow</strong>.</p>



<p class="wp-block-paragraph">ADRs, or <strong>architecture decision records</strong>, are not a new idea. Eoin said he was already writing them as a graduate in the 1990s, and even then they were not common practice. The fact that the advice is old does not make it less relevant. If anything, the opposite is true.</p>



<p class="wp-block-paragraph">AI tooling is generating code faster than teams can inspect the assumptions that end up inside it. Requirements are still vague. Stakeholders still do not always understand the technical response and decisions are still too often left implicit.</p>



<p class="wp-block-paragraph">The result is more <strong>software with more hidden assumptions inside it</strong>.</p>



<p class="wp-block-paragraph">That is where architecture really begins, in the part of the work that makes those assumptions visible before production has to do it for you.</p>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph"></p>
<p>The post <a href="https://shiftmag.dev/why-good-architecture-still-fails-in-production-9894/">Why Good Architecture Still Fails in Production</a> appeared first on <a href="https://shiftmag.dev">ShiftMag</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Great Developers Are Curious, Creative, and Ready for AI</title>
		<link>https://shiftmag.dev/teresa-wu-infobip-shift-interview-10425/</link>
		
		<dc:creator><![CDATA[Anastasija Uspenski]]></dc:creator>
		<pubDate>Fri, 26 Jun 2026 13:07:25 +0000</pubDate>
				<category><![CDATA[Event]]></category>
		<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[Infobip Shift 2026]]></category>
		<category><![CDATA[JPMorgan Chase]]></category>
		<category><![CDATA[Teresa Wu]]></category>
		<guid isPermaLink="false">https://shiftmag.dev/?p=10425</guid>

					<description><![CDATA[<p>At Infobip Shift, accomplished speaker and engineer Teresa Wu will talk about how AI is transforming software delivery, multi-platform development, and the future of engineering teams.</p>
<p>The post <a href="https://shiftmag.dev/teresa-wu-infobip-shift-interview-10425/">Great Developers Are Curious, Creative, and Ready for AI</a> appeared first on <a href="https://shiftmag.dev">ShiftMag</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Infobip Shift conference, <a href="https://shiftmag.dev/infobip-shift-2026-returns-to-zadar-bringing-apple-and-nvidia-to-the-stage-9585/" target="_blank" rel="noreferrer noopener nofollow">one of Europe&#8217;s biggest (and best) developer events</a> and a sister project to ShiftMag, is just three months away! As the buildup to the event continues, we&#8217;re kicking off talks with some of the Infobip Shift speakers to discuss their views on software development and find out sneak peeks about their talks. </p>



<h2 class="wp-block-heading"><span id="join-us-on-the-beautiful-croatian-coast">Join us on the beautiful Croatian coast</span></h2>



<p class="wp-block-paragraph">Speaking of sneak peeks, reading this article <strong><a href="https://www.entrio.hr/event/infobip-shift-2026-27033?pc=MAG15" target="_blank" rel="noreferrer noopener">makes</a> <a href="https://www.entrio.hr/en/event/infobip-shift-2026-27033?pc=MAG15" target="_blank" rel="noreferrer noopener">you eligible for a discount on Infobip Shift tickets</a></strong>. You&#8217;re welcome.</p>



<p class="wp-block-paragraph">To kick things off, I had the opportunity and pleasure to talk with one of this year&#8217;s speakers,<strong>Teresa Wu.</strong> <strong>In addition to her work as the VP Engineer at JPMorgan Chase</strong>, Teresa is also a Google Developer Expert (GDE), an accomplished public speaker and mentor. </p>



<p class="wp-block-paragraph">She has worked with many talented developers on various apps and projects over the years, and she enjoys exploring the world of multi-platform development, the fun of continuous delivery, and following a product from development to release.</p>



<p class="wp-block-paragraph">Her experience makes her the ideal person to talk to about today&#8217;s tech landscape, especially in the era of AI. So we did just that, and also talked about the perspective of an experienced mentor and public speaker. Teresa also shared some hints of her upcoming talk at Shift! </p>



<h2 class="wp-block-heading"><span id="ai-accelerates-multi-platform-development">AI accelerates multi-platform development</span></h2>



<p class="wp-block-paragraph">Throughout her career, Teresa has worked in front-end development, cloud technologies, and multi-platform products.<br>Currently, she is most inspired by multi-platform development, which she finds very exciting because, <strong>by using a single codebase combined with AI-powered automation</strong>, we can significantly speed up code generation and easily adapt user interfaces for iOS, Android, and web platforms:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">In this way, traditional barriers between platforms are removed and the time needed to bring a product to market is significantly reduced. This allows engineering teams to overcome technical limitations and fully focus on rapidly delivering value to end users.</p>
</blockquote>



<h2 class="wp-block-heading"><span id="ai-is-nothing-without-people">AI is nothing without people!</span></h2>



<p class="wp-block-paragraph">When asked how she sees the impact of artificial intelligence on the daily work of software engineers, Wu notes that AI is constantly evolving, creating a kind of feedback loop in which what we build today <strong>becomes training data for tomorrow’s</strong> systems:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">AI frees us from routine and repetitive tasks, but it still relies on people when it comes to defining rules, guiding processes, and creating new patterns of thinking. That is exactly where human creativity, experience, and judgment remain irreplaceable.</p>
</blockquote>



<h2 class="wp-block-heading"><span id="professional-growth-is-impossible-without-enthusiasm">Professional growth is impossible without enthusiasm</span></h2>



<p class="wp-block-paragraph">As a mentor and experienced public speaker, Teresa believes that sustainable professional development is almost impossible without genuine interest in what you do. That’s why she tries to find technology or projects that truly interest her, whether within her job or outside of it, and to find personal motivation in them:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">For me, public speaking is not just an opportunity to present knowledge; it is a way to explore new ideas and build a network of friends and professional contacts. When you align your learning with what truly drives you, professional growth becomes a natural and fulfilling consequence.</p>
</blockquote>



<h2 class="wp-block-heading"><span id="shift-conference-as-an-opportunity-to-expand-knowledge">Shift conference as an opportunity to expand knowledge</span></h2>



<p class="wp-block-paragraph">For Wu, this will be the first time speaking at (or visiting) <a href="https://shift.infobip.com/" target="_blank" rel="noreferrer noopener">Infobip Shift</a>. She decided to participate because the event brilliantly combines cutting-edge technologies and a vibrant community of experts, and is especially looking forward to the unique atmosphere of a large tech festival in Zadar.</p>



<p class="wp-block-paragraph">In addition, the opportunity to explore a beautiful destination while connecting with a global network of developers represents the perfect personal motivation for gaining new ideas and inspiration.</p>



<h3 class="wp-block-heading"><span id="much-more-than-just-code">Much more than just code!</span></h3>



<p class="wp-block-paragraph">As she points out, Teresa’s main goal is to gain a new perspective on how engineering teams use AI-based automation:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">Beyond technical talks, I place great value on people and conversations. What I especially appreciate about Shift is that it’s not just about code, but about the unique energy of thousands of developers trying together to understand what the future brings. I want to bring that inspiration into my everyday work as well.</p>
</blockquote>



<h3 class="wp-block-heading"><span id="sneak-peek-of-the-shift-talk">Sneak peek of the Shift talk</span></h3>



<p class="wp-block-paragraph">Without revealing too many details, I asked Teresa to hint at the topic of her talk and what can attendees expect to learn or take away from it: </p>



<ul class="wp-block-list">
<li><strong>Problem:</strong> Engineers responsible for software releases spend up to 40% of their time on manual processes and overly large change packages.</li>



<li><strong>AI-driven transformation:</strong> Moving from simple code-writing assistance to an autonomous “Release Pilot.”</li>



<li><strong>Data-driven decisions:</strong> Replacing subjective “go/no-go” decisions with an AI index that evaluates stability signals and system observability.</li>



<li><strong>Implementation plan:</strong> A 90-day migration path that significantly reduces manual work and enables faster, more efficient software delivery.</li>
</ul>



<p class="wp-block-paragraph"><strong>Want to hear Teresa live? <a href="https://www.entrio.hr/en/event/infobip-shift-2026-27033?pc=MAG15" type="link" id="https://www.entrio.hr/event/infobip-shift-2026-27033?pc=MAG15" target="_blank" rel="noreferrer noopener">Purchase your Shift ticket and use code <strong><em>MAG15</em></strong> for a discount</a>!</strong></p>


<figure class="wp-block-post-featured-image"><img loading="lazy" decoding="async" width="1200" height="630" src="https://shiftmag.dev/wp-content/uploads/2026/06/teresa-wu-header-shiftmag.png?x94846" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="" style="object-fit:cover;" srcset="https://shiftmag.dev/wp-content/uploads/2026/06/teresa-wu-header-shiftmag.png 1200w, https://shiftmag.dev/wp-content/uploads/2026/06/teresa-wu-header-shiftmag-300x158.png 300w, https://shiftmag.dev/wp-content/uploads/2026/06/teresa-wu-header-shiftmag-1024x538.png 1024w, https://shiftmag.dev/wp-content/uploads/2026/06/teresa-wu-header-shiftmag-768x403.png 768w" sizes="auto, (max-width: 1200px) 100vw, 1200px" /></figure><p>The post <a href="https://shiftmag.dev/teresa-wu-infobip-shift-interview-10425/">Great Developers Are Curious, Creative, and Ready for AI</a> appeared first on <a href="https://shiftmag.dev">ShiftMag</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>A Future Where Nobody Writes Code Manually Might Be Closer Than It Seems</title>
		<link>https://shiftmag.dev/future-no-one-writes-code-manually-10471/</link>
		
		<dc:creator><![CDATA[Ivan Simic]]></dc:creator>
		<pubDate>Thu, 25 Jun 2026 13:35:45 +0000</pubDate>
				<category><![CDATA[Artificial Intelligence]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[development]]></category>
		<guid isPermaLink="false">https://shiftmag.dev/?p=10471</guid>

					<description><![CDATA[<p>As AI tools reshape how software is built, the engineers in our new video say the job is shifting from writing every line by hand to guiding, reviewing, and orchestrating what AI produces.</p>
<p>The post <a href="https://shiftmag.dev/future-no-one-writes-code-manually-10471/">A Future Where Nobody Writes Code Manually Might Be Closer Than It Seems</a> appeared first on <a href="https://shiftmag.dev">ShiftMag</a>.</p>
]]></description>
										<content:encoded><![CDATA[<figure class="wp-block-post-featured-image"><img loading="lazy" decoding="async" width="1280" height="720" src="https://shiftmag.dev/wp-content/uploads/2026/06/Thumb_2.jpg?x94846" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="" style="object-fit:cover;" srcset="https://shiftmag.dev/wp-content/uploads/2026/06/Thumb_2.jpg 1280w, https://shiftmag.dev/wp-content/uploads/2026/06/Thumb_2-300x169.jpg 300w, https://shiftmag.dev/wp-content/uploads/2026/06/Thumb_2-1024x576.jpg 1024w, https://shiftmag.dev/wp-content/uploads/2026/06/Thumb_2-768x432.jpg 768w" sizes="auto, (max-width: 1280px) 100vw, 1280px" /></figure>


<p class="wp-block-paragraph">Once again, we brought together some of the finest minds Infobip has to answer tricky questions about the future of software. </p>



<p class="wp-block-paragraph">This time around, we spoke to four Infobip engineers about <strong>how they use AI in their daily work</strong> and how they view the AI revolution happening now.</p>



<h2 class="wp-block-heading"><span id="research-plan-execute">Research, plan, execute</span></h2>



<p class="wp-block-paragraph">With rapidly changing AI infrastructure, the things that used to be normal in software development are getting different, but some things stay the same. </p>



<p class="wp-block-paragraph"><strong>Petar Dučić</strong>, Engineering Director, said that the company&#8217;s mantra <strong>&#8220;you build it, you own it&#8221; has remained the same in the AI era</strong>. This simply means that engineers are responsible for whatever they build.</p>



<p class="wp-block-paragraph">Senior IT Research Scientist <strong>Ante Kapetanović</strong>, added that engineers need to <strong>separate their work phases </strong>efficiently:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">You have to separate your research phase, your planning phase, and your coding implementation, whatever phase. This ultimately means that you own each step of the way. And basically, it is not AI-assisted coding, it is more human-assisting AI.</p>
</blockquote>



<h2 class="wp-block-heading">Engineering is now becoming even more necessary&#8230;</h2>



<p class="wp-block-paragraph">It&#8217;s true that using AI tools is, in many cases, a cheaper alternative to real people, but Petar pointed out that engineering is now becoming even more necessary, because there&#8217;s so many things that can go wrong, and <strong>we need real people to check them</strong> and undestand what&#8217;s going on.</p>



<p class="wp-block-paragraph">Senior Software Engineer<strong> Rino Čala</strong> pointed out that there&#8217;s <strong>three types of mistakes agentic tools make</strong>: logical mistakes, code-based mistakes and security mistakes. The solution is, as Rino puts it, just more tests:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">So it is definitely important to run tests, to run some local tests, CI tests, and do some static checks as well.</p>
</blockquote>



<p class="wp-block-paragraph"><strong>Zvonimir Petković</strong>, Staf Engineer, then explained that <strong>security issues</strong> are the number one flaw with AI software tools:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">Security is the main risk with deploying Gen-AI generated code. With the whole Vibe coding setup, nobody looks at the code, and oftentimes we have also non-engineers deploying code. The hiding sensitive data within the source code itself, this is the number one problem.</p>
</blockquote>



<p class="wp-block-paragraph">The second problem for Zvonimir is <strong>scalability</strong>. Something that is built in a couple days might work fine for a small team, but cannot be scaled to 5,000 people easily.</p>



<h2 class="wp-block-heading">&#8230; and engineers are now more orchestrators than code writers</h2>



<p class="wp-block-paragraph">A stark contrast to the narrative of AI taking away jobs for engineers is that, with more people actively using AI, there&#8217;s a <strong>bigger need for someone with a technical background </strong>to help with not just support, but education.</p>



<p class="wp-block-paragraph">&#8220;We&#8217;re slowly becoming context engineers&#8221;, added Ante, saying that engineers are now spending a lot of time managing their context in different AI tools. He is personally a big advocate for writing your own code and feels like this is a major part of being an engineer. Still, Ante admits that might not be the case in a couple years.</p>



<p class="wp-block-paragraph">Zvonimir, interestingly, had a take about exactly that:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">The total trend is that in a few years&#8217; time, we&#8217;ll have the situation where nobody writes the code manually. Software engineers will be like persons who are the experts in that field, so they will be able to review what gen AI has generated.</p>
</blockquote>



<p class="wp-block-paragraph">In conclusion, as Rino puts it, engineers are now more in the role of orchestrators and organizers than they are code writes, since they spend a lot of time managing AI models to do things properly.</p>



<p class="wp-block-paragraph"><strong>Want to hear more? Check out the video.</strong></p>



<p class="wp-block-paragraph"><em>Special thanks to our fellow colleagues at Infobip, the publisher of ShiftMag!</em></p>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="From Code Writers to Agent Managers" width="500" height="281" src="https://www.youtube.com/embed/KGTQ7vG6ofo?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>
<p>The post <a href="https://shiftmag.dev/future-no-one-writes-code-manually-10471/">A Future Where Nobody Writes Code Manually Might Be Closer Than It Seems</a> appeared first on <a href="https://shiftmag.dev">ShiftMag</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Tokens and PR velocity won’t tell you if your AI investment is paying off</title>
		<link>https://shiftmag.dev/measure-ai-investment-beyond-tokens-pr-velocity-10010/</link>
		
		<dc:creator><![CDATA[Mia Biberovic]]></dc:creator>
		<pubDate>Wed, 24 Jun 2026 13:24:28 +0000</pubDate>
				<category><![CDATA[Productivity]]></category>
		<category><![CDATA[Catherine Hicks]]></category>
		<category><![CDATA[CTO Craft]]></category>
		<category><![CDATA[Developer Productivity]]></category>
		<guid isPermaLink="false">https://shiftmag.dev/?p=10010</guid>

					<description><![CDATA[<p>Your AI metrics might be measuring the wrong thing. Dr. Catherine Hicks explains how to fix the theory, not the dashboards.</p>
<p>The post <a href="https://shiftmag.dev/measure-ai-investment-beyond-tokens-pr-velocity-10010/">Tokens and PR velocity won’t tell you if your AI investment is paying off</a> appeared first on <a href="https://shiftmag.dev">ShiftMag</a>.</p>
]]></description>
										<content:encoded><![CDATA[<figure class="wp-block-post-featured-image"><img loading="lazy" decoding="async" width="1200" height="630" src="https://shiftmag.dev/wp-content/uploads/2026/06/CTO-Day2-Catherine-Hicks.jpg?x94846" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="" style="object-fit:cover;" srcset="https://shiftmag.dev/wp-content/uploads/2026/06/CTO-Day2-Catherine-Hicks.jpg 1200w, https://shiftmag.dev/wp-content/uploads/2026/06/CTO-Day2-Catherine-Hicks-300x158.jpg 300w, https://shiftmag.dev/wp-content/uploads/2026/06/CTO-Day2-Catherine-Hicks-1024x538.jpg 1024w, https://shiftmag.dev/wp-content/uploads/2026/06/CTO-Day2-Catherine-Hicks-768x403.jpg 768w" sizes="auto, (max-width: 1200px) 100vw, 1200px" /></figure>


<p class="wp-block-paragraph">At CTO Craft Con, <strong>Dr. Catherine Hicks</strong> (founder of Catharsis Consulting and researcher on open-science work involving 15,000+ developers) argued that most engineering measurement failures aren’t really data problems.</p>



<p class="wp-block-paragraph">No matter how much dashboards you vibe-code (we all do that nowadays, don’t we?), the problem is theoretical: <strong>understanding what causal model your metrics are actually testing.</strong></p>



<h2 class="wp-block-heading"><span id="are-you-building-spite-lines">Are you building spite  lines?</span></h2>



<p class="wp-block-paragraph">Hicks opened with a historical detour that turned out to be her sharpest part of the argument. Probably a bit brutal from today&#8217;s point of view, but <strong>early electricity measurement </strong>looked straightforward: count the deaths, count the lumens, measure the hours of labor saved. </p>



<p class="wp-block-paragraph">Why the number of deaths? Those<strong> numbers made sense relative to what came before</strong>. Gas infrastructure occasionally caused sidewalks to explode. Zero to ten electrocution deaths in a neighborhood looked different once you remembered that twenty people you knew had died from the sidewalk going up.</p>



<p class="wp-block-paragraph">Measurement always encodes a comparison, and if you do not make that comparison explicit, your metric will mislead you.</p>



<p class="wp-block-paragraph">The more cutting example was the spite line. In early U.S. rural electrification, large power companies would create something called a <strong>spite line</strong>. It&#8217;s a single wire that ran through a region, sometimes connected to nothing more useful than a light in a shed, in order to legally claim the territory and block rural co-ops from building real infrastructure. The federal government that was<strong> measuring electrification by the presence of a line</strong> wasn’t measuring access but the exact opposite.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="853" src="https://shiftmag.dev/wp-content/uploads/2026/06/CTO-Day2-Catherine-Hicks-2-1024x853.jpg?x94846" alt="" class="wp-image-10172" srcset="https://shiftmag.dev/wp-content/uploads/2026/06/CTO-Day2-Catherine-Hicks-2-1024x853.jpg 1024w, https://shiftmag.dev/wp-content/uploads/2026/06/CTO-Day2-Catherine-Hicks-2-300x250.jpg 300w, https://shiftmag.dev/wp-content/uploads/2026/06/CTO-Day2-Catherine-Hicks-2-768x640.jpg 768w, https://shiftmag.dev/wp-content/uploads/2026/06/CTO-Day2-Catherine-Hicks-2.jpg 1200w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">CTO Craft Con</figcaption></figure>



<p class="wp-block-paragraph">Hicks argued that <strong>engineering organizations are building spite lines right now</strong>, and mostly do not know it.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">Measurement failures usually come back to theory failures.</p>
</blockquote>



<h2 class="wp-block-heading"><span id="the-loudest-thing-on-slack-might-not-be-the-most-important">The loudest thing (on Slack) might not be the most important</span></h2>



<p class="wp-block-paragraph">A change theory, in her framing, is a causal model: if I give engineers more ramp time on this language, they will engage differently with these processes, and that will produce a business outcome. Everyone operates inside such models, but most teams never make them explicit. </p>



<p class="wp-block-paragraph"><strong>The result is that they default to measuring what is visible, what is fast to collect, or what is loudest on Slack.</strong> None of those is necessarily connected to the outcome they care about.</p>



<p class="wp-block-paragraph">On AI specifically, she identified <strong>three recurring failure modes</strong>:</p>



<ol class="wp-block-list">
<li><strong>Treating developers as interchangeable units</strong>&nbsp;producing identical work, when they’re actually using AI in highly individual contexts.</li>



<li><strong>Reading early spikes in code volume as a stable signal</strong>, when research on open-source repositories shows those spikes often normalize into different patterns within weeks.</li>



<li><strong>Measuring only at the individual level</strong>&nbsp;while ignoring the interaction between the tool, the team, the task, the project goals, and organizational culture &#8211; a system Hicks said has too many interaction terms for any person to hold at once.</li>
</ol>



<p class="wp-block-paragraph">Her response to that complexity was deliberate:<strong> stop trying to measure everything</strong>.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">Your job is not to measure everything that&#8217;s happening. What you really need to do is think about what in your organization are the key signals to measure if they give you two things.</p>
</blockquote>



<p class="wp-block-paragraph">Those two things are levers, predictors of large behavioral patterns, or blockers you can actually remove, and shared outcomes you can hold the organization accountable to over time.</p>



<h2 class="wp-block-heading"><span id="correlation-between-learning-culture-and-team-effectiveness">Correlation between learning culture and team effectiveness</span></h2>



<p class="wp-block-paragraph">Hicks drew on her own research to illustrate what a well-theorized lever looks like. </p>



<p class="wp-block-paragraph">In a 2024 study of over 3,000 working developers, her team tested<strong> </strong><a href="https://shiftmag.dev/dr-cat-hicks-software-teams-psychology-5357/" target="_blank" rel="noreferrer noopener">whether learning culture could reduce the identity threat that developers report feeling from AI</a><strong>.</strong> Teams with strong learning cultures, defined as believing they have organizational support to learn, and rejecting fixed-mindset assumptions about what makes someone technically capable, cut their AI-related identity threat by 50% or more. She has since replicated the correlation between learning culture and team effectiveness across multiple engineering organizations, and found that reaching the highest effectiveness tier requires clearing a threshold of learning culture, not just improving incrementally.</p>



<p class="wp-block-paragraph">The practical upshot for leaders:<strong> if you want to measure whether your AI investment is working, you probably should not start with token consumption or PR velocity</strong>. You should <strong>ask whether developers believe their organization treats learning as legitimate work</strong>.</p>



<h2 class="wp-block-heading"><span id="what-if-your-metrics-are-broken">What if your metrics are broken?</span></h2>



<p class="wp-block-paragraph">On the question of what to actually do when you realize your metrics are broken, Hicks was direct. Describe how you got there. Find the argument you lost, or the organizational story that made a bad measure feel safe to commit to. <strong>Then build a change theory first, and derive the measures from that</strong>, not the other way around.</p>



<p class="wp-block-paragraph">She closed with a framing that captured her broader position: you are not trying to map every variable in a complex system. You are trying to create enough shared understanding that people will tell you what is actually happening.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">You will become the person who can hear what is really happening. You will be the person who will start to hear: I think we&#8217;re measuring spite lines over here.</p>
</blockquote>



<p class="wp-block-paragraph">That, she argued, is more useful than any dashboard.</p>
<p>The post <a href="https://shiftmag.dev/measure-ai-investment-beyond-tokens-pr-velocity-10010/">Tokens and PR velocity won’t tell you if your AI investment is paying off</a> appeared first on <a href="https://shiftmag.dev">ShiftMag</a>.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>

<!--
Performance optimized by W3 Total Cache. Learn more: https://www.boldgrid.com/w3-total-cache/?utm_source=w3tc&utm_medium=footer_comment&utm_campaign=free_plugin

Page Caching using Disk: Enhanced 

Served from: shiftmag.dev @ 2026-07-15 20:32:45 by W3 Total Cache
-->