<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Nestor Arocha</title>
    <description></description>
    <link>http://nestorarocha.com/</link>
    <atom:link href="http://nestorarocha.com/feed.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Thu, 06 Aug 2026 21:13:14 +0100</pubDate>
    <lastBuildDate>Thu, 06 Aug 2026 21:13:14 +0100</lastBuildDate>
    <generator>Jekyll v4.4.1</generator>
    
      <item>
        <title>Celery (python library) limitations</title>
        <description>&lt;p&gt;&lt;a href=&quot;https://docs.celeryq.dev/en/stable/getting-started/introduction.html&quot;&gt;celery&lt;/a&gt; is a python library to manage some concurrent workloads.&lt;/p&gt;

&lt;p&gt;Celery tasks are called from regular python code. They go through
a queue and get executed in a separate &lt;em&gt;worker&lt;/em&gt; process. The
results are sent back to a database available to the caller. Its
simplest form looks like this:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;task&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;delay&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arg1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arg2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kwarg1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kwarg2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;with celery managing everything if configured properly. In celery
it is possible to specify more complicated structures using
&lt;a href=&quot;https://docs.celeryq.dev/en/stable/userguide/canvas.html#the-primitives&quot;&gt;workflow primitives&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;groups&lt;/strong&gt; execute tasks in parallel. &lt;strong&gt;chords&lt;/strong&gt; call a final one
when all done&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;chains&lt;/strong&gt; execute tasks using the output of an entry as the input
of the next one, returning the final output&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;map&lt;/strong&gt; apply the same function to a set of inputs, and return the
outputs of each of them&lt;/p&gt;

&lt;h2 id=&quot;the-limitation&quot;&gt;The limitation&lt;/h2&gt;

&lt;p&gt;Celery is one of the many options for concurrent execution in
python. It is a bit more complicated that using threads or
subprocess, but resistant to the main process restarting. Unlike
asyncio it allows more than 1 cpu at a time.  It is less
complicated that using a database or stream processing where
guarantees of execution are stronger.&lt;/p&gt;

&lt;p&gt;But there is a weakness that after certain scale becomes
problematic: &lt;strong&gt;There is no permanent task storage over time&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;When a celery task runs, the task gets inserted in the queue.&lt;/li&gt;
  &lt;li&gt;When a worker is ready to run the task (or wants to prefetch it),
the task gets removed from the queue.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/assets/481aacff61ff0165a19c061b0e1dd9d3.png&quot; alt=&quot;481aacff61ff0165a19c061b0e1dd9d3&quot; /&gt;&lt;/p&gt;

&lt;p&gt;So for example, if the worker gets killed but the task isn’t
finished, what happens? The worker is responsible to put the task
back in the queue. In most circumstances it will be handled fine,
but under pressure, the task can receive a SIGKILL or produce a
exotic signal like SIGSEGV. Celery won’t handle this so the task
will be lost forever.&lt;/p&gt;

&lt;p&gt;It is possible to use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;acks_late&lt;/code&gt; as a property of the task. This
informs celery not to acknowledge the task until it is fully done.
The problem then is about running the task multiple times in case
of failure. This is the &lt;a href=&quot;https://www.confluent.io/blog/exactly-once-semantics-are-possible-heres-how-apache-kafka-does-it/&quot;&gt;exactly once&lt;/a&gt;
problem that kafka in particular aims to solve, although any
database with transactional guarantees offers the same.&lt;/p&gt;

&lt;p&gt;There is a complication to this limitation: Remember the workflows
I mentioned before? They live as tasks in the same system. So they
are either in the queue or in the workers’ memory. Any complicated
workflow will inevitably disappear and executed partially or get
executed multiple times in these situations.&lt;/p&gt;

&lt;h2 id=&quot;alternatives&quot;&gt;Alternatives&lt;/h2&gt;

&lt;p&gt;Some people suggest to use temporal.io . I think the lock in is
too unpalatable so rolling out something with redis, postgres or
kafka that has better guarantees could do.&lt;/p&gt;

&lt;p&gt;This depends on the complexity of the workflows though. For very
complicated workflows something like
&lt;a href=&quot;https://argoproj.github.io/workflows/&quot;&gt;https://argoproj.github.io/workflows/&lt;/a&gt; could work best.&lt;/p&gt;

&lt;hr /&gt;

&lt;ul&gt;
  &lt;li&gt;tags:&lt;a href=&quot;/a/tag/python/&quot;&gt;#python&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Thu, 06 Aug 2026 00:00:00 +0100</pubDate>
        <link>http://nestorarocha.com/2026/08/06/python-celery-limitations.html</link>
        <guid isPermaLink="true">http://nestorarocha.com/2026/08/06/python-celery-limitations.html</guid>
        
        <category>python</category>
        
        
      </item>
    
      <item>
        <title>I agree with codeberg&apos;s LLM contribution decision</title>
        <description>&lt;p&gt;Recently codeberg passed two motions regarding LLM usage:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://blog.codeberg.org/protecting-our-floss-commons-from-llms.html&quot;&gt;https://blog.codeberg.org/protecting-our-floss-commons-from-llms.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The first vote is about codeberg not using the hosted code to
train LLMs. The second one is the one I want to focus on; it
prohibits vibe coded projects on the platform.&lt;/p&gt;

&lt;p&gt;They mention in their post the “digital divide”. Large cloud
companies are the only ones able to afford the infrastructure to
handle all the costs associated with using LLM and being part of
the 2026. Smaller actors can’t afford to exist on their own and
instead they have to rent from the cloud providers.&lt;/p&gt;

&lt;p&gt;I strongly resonate with this divide as I perceive it constantly.
For example, I don’t think it would be possible for any startup to
create github today if it didn’t exist. The amount of noise of
slop projects would make too hard to serve legitimate users while
keeping it free or with a harmless “pay for private repos” that
github used to have.&lt;/p&gt;

&lt;p&gt;So codeberg had the option to try to accommodate to these forces
and become bigger and more corporate-like, or to stay small and
serving the people that want the community above the market or
energy forces.&lt;/p&gt;

&lt;h2 id=&quot;the-ecological-case&quot;&gt;The ecological case&lt;/h2&gt;

&lt;p&gt;Creating and modifying software involves effort. Developers have
to put the thought to understand and translate the requirements
into whatever needs to exist.&lt;/p&gt;

&lt;p&gt;Cloud availability has accelerated the conversion from thought and
reading into literal computer effort. I am talking about
pipelines, deployments and other verification tools. Some of the
effort has shifted to a computer running in the cloud, reducing
the amount of human effort. Simply push the code and the pipeline
will run.&lt;/p&gt;

&lt;p&gt;LLMs are a big step in the same direction. A set of prompts and
documents (a specification) plus a lot of energy and materials in
a data centre produce plausible code. Leaving aside how good the
code is, it reduces the amount of human effort to generate code. I
wrote on this trade off recently:&lt;/p&gt;

&lt;p&gt;[[&lt;a href=&quot;/2026/03/15/the-llm-code-bet.html&quot;&gt;2026-03-15-the-llm-code-bet&lt;/a&gt;]]&lt;/p&gt;

&lt;p&gt;Both in the cloud revolution and in the AI revolution, the human
cost of creating software goes down. Jevon’s paradox seems at play
in here as these changes have increased the amount of code
produced.&lt;/p&gt;

&lt;p&gt;At the same time, LLMs have reduced the effect of trust and human
networks in the process. The proof of work is not there. So I
believe that people are less trusting of new projects unless they
come with some guarantee in the form of robust tests, verification
or guardrails.&lt;/p&gt;

&lt;p&gt;The new ways of work require more energy to generate code, more
energy to verify the code and also produce more software in
general. It makes sense if energy is very cheap.&lt;/p&gt;

&lt;h2 id=&quot;the-bill-please&quot;&gt;The bill please&lt;/h2&gt;

&lt;p&gt;So who is paying for this extra energy cost? I would say
originally the investor class paid for it, looking for future
profits. As LLMs improved, working people are starting to pay
directly by losing their jobs. We are also losing by losing access
to personal computing.&lt;/p&gt;

&lt;p&gt;Energy wise the extra demands come from other sectors of
investment. All the capital that go into data centres is not
available for something else, like infrastructure, health care or
education.&lt;/p&gt;

&lt;p&gt;Ultimately the capital cost reflects the cost to nature so we are
all losing out on that one, although we call it externalities.&lt;/p&gt;

&lt;p&gt;This is why I think codeberg is right not to be part of this extra
cost dynamic, and wait until we find the amount of LLM usage that
actually increases productivity without increasing energy or human
collaboration costs.&lt;/p&gt;

&lt;p&gt;P.S.: I haven’t mentioned the likely bubble bursting nor that the
multiple wars around oil will likely impact the price of energy,
making LLM software development fragile. Maybe another day.&lt;/p&gt;

&lt;hr /&gt;

&lt;ul&gt;
  &lt;li&gt;tags:&lt;a href=&quot;/a/tag/llm/&quot;&gt;#llm&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Wed, 05 Aug 2026 00:00:00 +0100</pubDate>
        <link>http://nestorarocha.com/2026/08/05/i-agree-with-codeberg.html</link>
        <guid isPermaLink="true">http://nestorarocha.com/2026/08/05/i-agree-with-codeberg.html</guid>
        
        <category>llm</category>
        
        
      </item>
    
      <item>
        <title>On Conway&apos;s law</title>
        <description>&lt;p&gt;Conway’s law is a well known “law” of systems. It is an
observation really:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Organizations which design systems (in the broad sense used
here) are constrained to produce designs which are copies of the
communication structures of these organizations.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Conway&apos;s_law&quot;&gt;https://en.wikipedia.org/wiki/Conway&apos;s_law&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Martin Fowler also wrote similarly:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The key thing to remember about Conways Law is that the modular
decomposition of a system and the decomposition of the
development organization must be done together. This isn’t just
at the beginning, evolution of the architecture and reorganizing
the human organization must go hand-in-hand throughout the life
of an enterprise.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href=&quot;https://martinfowler.com/bliki/ConwaysLaw.html&quot;&gt;https://martinfowler.com/bliki/ConwaysLaw.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I would distill it as “codified systems follow, at best, the
structure of the system that produces it”. This matches my
personal experience.&lt;/p&gt;

&lt;p&gt;Companies that do understand Conway’s law try to modify both the
existing code structure and the organisational structure, slowly
nudging both towards the desired structure. Or allow the teams to
be flexible to nudge the system structure towards the company
goals.&lt;/p&gt;

&lt;p&gt;Companies that do not understand Conway’s law produce a structure
that does not reflect the existing codebase structure, and instead
focus on the expected business structure.&lt;/p&gt;

&lt;p&gt;This creates a divergence between the code structure, its ownership
and s responsibilities that translate into debt and constant
wasted resources of dealing with the ever growing divergence&lt;/p&gt;

&lt;h2 id=&quot;the-mirroring-hypothesis&quot;&gt;The mirroring hypothesis&lt;/h2&gt;

&lt;p&gt;Recently I came across “Exploring the Duality between Product and
Organizational Architectures: A Test of the “Mirroring”
Hypothesis” Alan MacCormack, John Rusnak, Carliss Baldwin explore
the vailidity of the mirroring hypothesis&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://thinkinglabs.io/articles/2026/06/20/beyond-shades-of-conways-law-validation.html&quot;&gt;https://thinkinglabs.io/articles/2026/06/20/beyond-shades-of-conways-law-validation.html&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.hbs.edu/ris/Publication%20Files/08-039_1861e507-1dc1-4602-85b8-90d71559d85b.pdf&quot;&gt;https://www.hbs.edu/ris/Publication%20Files/08-039_1861e507-1dc1-4602-85b8-90d71559d85b.pdf&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The mirroring hypothesis I interpret as a weaker version of
conway’s law:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The mirroring hypothesis predicts that these different
organizational forms will produce products with distinctly
different architectures. Specifically, loosely-coupled
organizations will develop more modular designs than
tightly-coupled organizations.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It refers to the “modularity” or “coupling” aspect
of conway’s law rather than the particular&lt;/p&gt;

&lt;p&gt;They found strong evidence to support the mirroring hypothesis. I
also believe this is a strong arguments for self organised units,
similar to what agile proposes. Fred Emery coined the two design
principles.&lt;/p&gt;

&lt;h2 id=&quot;dp1-and-dp2&quot;&gt;DP1 and DP2&lt;/h2&gt;

&lt;p&gt;DP1 and DP2 are that two design principles that Fred Emery
attributed to all forms of organisation.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://ingbrief.wordpress.com/2012/03/02/genotypical-organization-design-principles-dp1-and-dp2-merrelyn-emery/&quot;&gt;https://ingbrief.wordpress.com/2012/03/02/genotypical-organization-design-principles-dp1-and-dp2-merrelyn-emery/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;DP1&lt;/strong&gt; is the redundancy of parts. So many parts do the same
thing to preserve the organisation. Think of managers referring to
the same work and autocracy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DP2&lt;/strong&gt; is the redundancy of functions. Each component of the
organisation has the ability to do the same thing and they
collaborate. It is democratic.&lt;/p&gt;

&lt;p&gt;There is also the &lt;strong&gt;Laissez-faire&lt;/strong&gt; which refers to organisations
that fail to follow any of these arrangements.&lt;/p&gt;

&lt;p&gt;I believe that Conway’s law, the agile formulation of acting as an
independent cell with redundant functions and &lt;strong&gt;DP2&lt;/strong&gt; structures
refer to the same thing. They are all about keeping an eye on the
structure to fix things structurally, and enable the modularity
that resilient structures exhibit.&lt;/p&gt;

&lt;p&gt;They are politics so they are hard to optimise for. Without team
or business structure considerations, rigid authoritarian or
chaotic outcomes dominate the company which are counterproductive
in different ways.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;tags:&lt;a href=&quot;/a/tag/architecture/&quot;&gt;#architecture&lt;/a&gt; &lt;a href=&quot;/a/tag/design/&quot;&gt;#design&lt;/a&gt; &lt;a href=&quot;/a/tag/software/&quot;&gt;#software&lt;/a&gt;&lt;/p&gt;
</description>
        <pubDate>Mon, 13 Jul 2026 00:00:00 +0100</pubDate>
        <link>http://nestorarocha.com/2026/07/13/on-conways-law.html</link>
        <guid isPermaLink="true">http://nestorarocha.com/2026/07/13/on-conways-law.html</guid>
        
        <category>architecture</category>
        
        <category>design</category>
        
        <category>software</category>
        
        
      </item>
    
      <item>
        <title>The whale fall</title>
        <description>&lt;p&gt;Whales can live longer than a human. They follow Kleiber’s law, so
bigger whales will consume less energy per unit of mass, which is
corelated with longer lifespan. Bigger whales live longer on
average.&lt;/p&gt;

&lt;p&gt;But even if they lived thousands of years, they are not immortal.
When they die, gravity takes over. Buoyancy doesn’t work if the
air inside them escapes. If they are far enough from the coast,
they will inevitably fall to the bottom of the sea.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Whale_fall&quot;&gt;https://en.wikipedia.org/wiki/Whale_fall&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But life imposes it cycles everywhere with its ecological logic.
Various organisms populate the remains as they provide a new
opportunity to growth.&lt;/p&gt;

&lt;h2 id=&quot;a-mental-experiment&quot;&gt;A mental experiment&lt;/h2&gt;

&lt;p&gt;With this carcass on the ocean floor in mind, I want to propose a
mental experiment: Imagine you are one of these microorganisms
that happened to find one of these carcasses. Big carcasses are
great opportunities to grow compared to small animals, so this is
a good place to be.&lt;/p&gt;

&lt;p&gt;After the organic material is all processed, there is a certain
amount of population that the carcass can support by acting as
inorganic coral. It is not a lot though.&lt;/p&gt;

&lt;p&gt;On the negative side, this is a very remote carcass. It is also
releasing radioactive particles whenever is processed. Releasing
these particles will reduce the chances of survival as it will
contaminate the whole ocean including the rest of the carcass.&lt;/p&gt;

&lt;p&gt;So here are some ideas on how to go about it:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Grow as fast as you can until the carcass depletes, then deal
with the crash later plus the radioactive particles&lt;/li&gt;
  &lt;li&gt;Invest on resilience by stopping growth and fighting competing
organisms. Note that this only works temporarily as a growing
organism will eventually use more resources to take over&lt;/li&gt;
  &lt;li&gt;Grow as little as possible or not at all but do not let others
take over, seeking for a low energy homeostasis&lt;/li&gt;
  &lt;li&gt;Leave entirely renouncing to the available growth&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What would you do?&lt;/p&gt;

&lt;h2 id=&quot;the-real-life-thing&quot;&gt;The real life thing&lt;/h2&gt;

&lt;p&gt;I could write that because of this year unprecedented heat waves,
climate catastrophe is around the corner. I feel like this has
been true for my whole life, and accelerated considerably. It will
still be true many years in the future.&lt;/p&gt;

&lt;p&gt;As small organisms part of human society, we have some choices or
at least &lt;em&gt;tendencies&lt;/em&gt; to act one way or another.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Some people see growth as a goal and something to strive for, so
there is no drawback to it even if the crash is bigger later&lt;/li&gt;
  &lt;li&gt;Some people will actively invest on local resiliency. This only
works if the extra resources cannot be retaken, so timing is
critical&lt;/li&gt;
  &lt;li&gt;Some people will not invest on either, and try to live within
their means. Other people that grow too much can make this
unstable too&lt;/li&gt;
  &lt;li&gt;Some people withdraw entirely and refuse to be part of the
system. They move to somewhere far away where they can be self
sufficient, though other’s growth can make this unstable over
long term too&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Any choice that isn’t growth requires good timing and common
restrain. Is it possible to choose with competition? What would
you do?&lt;/p&gt;

&lt;hr /&gt;

&lt;ul&gt;
  &lt;li&gt;tags:&lt;a href=&quot;/a/tag/ecology/&quot;&gt;#ecology&lt;/a&gt; &lt;a href=&quot;/a/tag/climatechange/&quot;&gt;#climatechange&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Tue, 07 Jul 2026 00:00:00 +0100</pubDate>
        <link>http://nestorarocha.com/2026/07/07/the-whale-fall.html</link>
        <guid isPermaLink="true">http://nestorarocha.com/2026/07/07/the-whale-fall.html</guid>
        
        <category>climatechange</category>
        
        <category>ecology</category>
        
        
      </item>
    
      <item>
        <title>Measuring import time in python</title>
        <description>&lt;p&gt;In python a code file can do arbitrary stuff. They can connect to
a server, calculate something complicated or have enormous
literals to parse.&lt;/p&gt;

&lt;p&gt;When projects get big, this is a problem because the import time
compounds and most people and code dislike imports inside function
or class scopes.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://docs.python.org/3.15/reference/simple_stmts.html#lazy-imports&quot;&gt;lazy imports&lt;/a&gt;
appeared in python 3.15 and allows deferring the actual import
while keeping them at the top of the file.&lt;/p&gt;

&lt;p&gt;In both cases deferring the import introduces arbitrary waits that
are not predictable. They also can affect the state of the program
by patching, forking or performing any other side effect
operation that depends on order.&lt;/p&gt;

&lt;p&gt;Sometimes it is better to measure the import time and make the
changes so the expensive code runs in the appropriate context.&lt;/p&gt;

&lt;h2 id=&quot;the-post-38-way&quot;&gt;The post 3.8 way&lt;/h2&gt;

&lt;p&gt;Python now includes &lt;a href=&quot;https://docs.python.org/3/using/cmdline.html#envvar-PYTHONPROFILEIMPORTTIME&quot;&gt;import time&lt;/a&gt;
in its standard library.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://stackoverflow.com/questions/34755728/profile-python-import-times&quot;&gt;https://stackoverflow.com/questions/34755728/profile-python-import-times&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This method requires no code changes and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tuna&lt;/code&gt; allows to see the
visualise the output without.&lt;/p&gt;

&lt;h2 id=&quot;the-custom-or-pre-37-way&quot;&gt;The custom or pre 3.7 way&lt;/h2&gt;

&lt;p&gt;Back in the day with python 3.6 patching the easiest way to get
the information was to patch the import system&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dataclasses&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dataclass&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;inspect&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;importlib.machinery&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;time&lt;/span&gt;

&lt;span class=&quot;nd&quot;&gt;@dataclass&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ImportDuration&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;duration&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;float&lt;/span&gt;

    &lt;span class=&quot;nd&quot;&gt;@property&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;calculated_duration&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;duration&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;duration&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;children&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

    &lt;span class=&quot;nd&quot;&gt;@property&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;children&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IMPORT_DURATIONS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;IMPORT_DURATIONS&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;_genrate_loader_details&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;sh&quot;&gt;&quot;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Returns a list of file-based module loaders.
    &lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;extensions&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;importlib&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;machinery&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ExtensionFileLoader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;importlib&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;machinery&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;EXTENSION_SUFFIXES&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;source&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MyLoader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;importlib&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;machinery&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SOURCE_SUFFIXES&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;bytecode&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;importlib&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;machinery&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SourcelessFileLoader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;importlib&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;machinery&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BYTECODE_SUFFIXES&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;extensions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bytecode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyLoader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;importlib&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;machinery&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SourceFileLoader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;exec_module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;start&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;exec_module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;duration&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;start&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;module_file&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__file__&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;module_file&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IMPORT_DURATIONS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;stack&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;inspect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;stack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;parent_filename&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;IMPORT_DURATIONS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;module_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ImportDuration&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;module_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent_filename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;duration&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path_hooks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;importlib&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;machinery&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FileFinder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;path_hook&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;_genrate_loader_details&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__name__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;__main__&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cogapp&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# any import that we want to measure
&lt;/span&gt;    &lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pprint&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pprint&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;pprint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;sorted&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;calculated_duration&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;
                   &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IMPORT_DURATIONS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()],&lt;/span&gt;
                  &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The main idea is:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Reimplement &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SourceFileLoader&lt;/code&gt; by adding the timing code around
the actual loading. &lt;a href=&quot;https://docs.python.org/3/library/importlib.html#importlib.machinery.SourceFileLoader&quot;&gt;docs&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Tell the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FileFinder&lt;/code&gt; to use the new loader for loading python files using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.path_hook&lt;/code&gt;
&lt;a href=&quot;https://docs.python.org/3/library/importlib.html#importlib.machinery.FileFinder.path_hook&quot;&gt;docs&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Run the actual code&lt;/li&gt;
  &lt;li&gt;Inspect the data structure where the timing information is
stored&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I don’t remember where I got this code nor how much did I have to
fine tune it, but I remember getting the signatures like the
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;loader_details&lt;/code&gt; being hard.&lt;/p&gt;

&lt;p&gt;This method has the advantage of being fully customisable so for
example it can run for imports after forking, or raise an
exception if an import goes above certain duration.&lt;/p&gt;

&lt;hr /&gt;

&lt;ul&gt;
  &lt;li&gt;tags:&lt;a href=&quot;/a/tag/python/&quot;&gt;#python&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Sun, 05 Jul 2026 00:00:00 +0100</pubDate>
        <link>http://nestorarocha.com/2026/07/05/measuring-import-time-in-python.html</link>
        <guid isPermaLink="true">http://nestorarocha.com/2026/07/05/measuring-import-time-in-python.html</guid>
        
        <category>python</category>
        
        
      </item>
    
      <item>
        <title>Postgres: Long transactions and Access exclusive locks</title>
        <description>&lt;p&gt;I would like to share a postgres story that has happened to me a
few times.&lt;/p&gt;

&lt;p&gt;The story has the following ingredients:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;An overly centralised Entity/Relationship model&lt;/li&gt;
  &lt;li&gt;Long database transactions to aid data consistency&lt;/li&gt;
  &lt;li&gt;Schema migration of tables&lt;/li&gt;
  &lt;li&gt;Poor observability of transactions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;1. Centralised tables&lt;/strong&gt; go like this: A database with many FK to a
to a central table in the business logic that hasn’t been properly
designed works fine most of the time.&lt;/p&gt;

&lt;p&gt;Django or any other MVC (MTV) frameworks that manage the database
schema and include some central tables (like User) suffer from
this issue&lt;/p&gt;

&lt;p&gt;As the system grows, many models FK directly to the existing
models rather than redesigning the database to reduce the number
of FKs to a single model. These models become accidental
&lt;em&gt;Aggregates&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Long database transactions&lt;/strong&gt; are a common pattern in MVC
frameworks: As the system grows, more and more database operations
need to happen with transactional guarantees. These frameworks
offer the option to use the database transaction to coordinate all
of these operations.&lt;/p&gt;

&lt;p&gt;In web applications where many workers access the same database,
this is a good trade off as it can be represented in code without
any external tools. Generally this coordination of what needs to
be simultaneous is one of the hard problems to figure out in a
system.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Schema migrations of tables&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;These are also common in MVC frameworks. In python both django and
alembic offer to manage the database schema by reading the model
definitions from python files. But partly because of their ease to
change and apply, in some configurations these happen at any time.&lt;/p&gt;

&lt;h2 id=&quot;everything-works-fine-until-it-doesnt&quot;&gt;Everything works fine until it doesn’t&lt;/h2&gt;

&lt;p&gt;Imagine the following set of N transactions:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
T1 -&amp;gt; T2 -&amp;gt; T3 -&amp;gt; T4 -&amp;gt; T5 -&amp;gt; ... -&amp;gt; TN

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;None of these factors cause issues on their own.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Accidental aggregates add extra cost to any FK changes, but not
enough to be noticeable.&lt;/li&gt;
  &lt;li&gt;Long transactions could cause a problem, but most of
the time the will lock individual rows and not interfere with
other operations.&lt;/li&gt;
  &lt;li&gt;Schema changes could block the database briefly because of the
expensive table lock, but avoiding changing already populated
big tables is generally enough&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Combining all of these though can cause the database to become
unresponsive. Something as simple as creating a new table with a
FK to a central table has the power to block any operation that
reads or writes the central table.&lt;/p&gt;

&lt;p&gt;So for the same set of transactions:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;T2 is a long transaction&lt;/li&gt;
  &lt;li&gt;T3 is a schema change that requires &lt;em&gt;Access Exclusive&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
T1 -&amp;gt; T2(Long) -&amp;gt; T3(Lock) -&amp;gt; T4 -&amp;gt; T5 -&amp;gt; ... -&amp;gt; TN

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If T2 was short, T3 would be able to start immediately. If T3
didn’t lock the whole table, it would allow the subsequent
transactions to continue.&lt;/p&gt;

&lt;p&gt;In this scenario:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T4 -&amp;gt; ... -&amp;gt; TN&lt;/code&gt; are all blocked by T3 because
they all refer to the centralised model and postgres honours the
order of operations.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T3&lt;/code&gt; is blocked until &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T2&lt;/code&gt; finishes because its lock requires
no other operation running on the table&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So no read operation happens to any table affected until &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T2&lt;/code&gt; and
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T3&lt;/code&gt; are done. Which is enough to bring a web app down.&lt;/p&gt;

&lt;h2 id=&quot;bad-visibility&quot;&gt;Bad visibility&lt;/h2&gt;

&lt;p&gt;These type of issues are hard to see from regular observability
tools like datadog and grafana.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://grafana.com/docs/grafana-cloud/monitor-infrastructure/integrations/integration-reference/integration-postgres/&quot;&gt;https://grafana.com/docs/grafana-cloud/monitor-infrastructure/integrations/integration-reference/integration-postgres/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My personal experience is with datadog. It is possible to see the
long queries and the long transactions but it is impossible to
attribute causality to it. So if your system features long
transactions and frequent schema changes, it will take some time
to infer which transaction caused it and what to do&lt;/p&gt;

&lt;h2 id=&quot;solutions&quot;&gt;Solutions&lt;/h2&gt;

&lt;p&gt;There are many ways to tackle mitigate the risk of this scenario:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Plan for downtime&lt;/strong&gt;
For some systems this might be a viable option: Establish a time
of the day where the schema change happen, avoid long transactions
during that time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use write constraints&lt;/strong&gt;
&lt;a href=&quot;https://medium.com/doctolib/adding-a-not-null-constraint-on-pg-faster-with-minimal-locking-38b2c00c4d1c&quot;&gt;https://medium.com/doctolib/adding-a-not-null-constraint-on-pg-faster-with-minimal-locking-38b2c00c4d1c&lt;/a&gt;
It is possible to avoid using Foreign keys entirely and instead
use a constraint. It will mitigate the risk of locking but add a penalty on every single write&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Disallow long transactions&lt;/strong&gt;
Postgres allows to cancel long transactions
&lt;a href=&quot;https://www.postgresql.org/docs/17/runtime-config-client.html#GUC-TRANSACTION-TIMEOUT&quot;&gt;https://www.postgresql.org/docs/17/runtime-config-client.html#GUC-TRANSACTION-TIMEOUT&lt;/a&gt;
It is feasible to refactor the application to rely on external
mechanisms instead of database locks. Even an advisory lock will
be enough as it doesn’t use any particular table.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Refactor the models&lt;/strong&gt;
If having a central model causes this problem, separating the
models within or even outside the database will fix it.
Moving the coordination away from a single database has its own
trade offs. Added complexity and out of order operations are
common in microservice architectures.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;*&lt;a href=&quot;/a/tag/postgres/&quot;&gt;#postgres&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.postgresql.org/docs/current/explicit-locking.html#LOCKING-TABLES&quot;&gt;https://www.postgresql.org/docs/current/explicit-locking.html#LOCKING-TABLES&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Thu, 02 Jul 2026 00:00:00 +0100</pubDate>
        <link>http://nestorarocha.com/2026/07/02/postgres-long-transaction-and-access-exclusive.html</link>
        <guid isPermaLink="true">http://nestorarocha.com/2026/07/02/postgres-long-transaction-and-access-exclusive.html</guid>
        
        <category>postgres</category>
        
        
      </item>
    
      <item>
        <title>Tiny Experiments review</title>
        <description>&lt;p&gt;&lt;a href=&quot;https://nesslabs.com/book&quot;&gt;tiny experiments&lt;/a&gt; by Anne-Laure Le
Cunff is a self help book. I found it in my local library in my
quest for deciding my next steps, although it was in the science
section instead of self help.&lt;/p&gt;

&lt;p&gt;I wrote recently on self help books:&lt;/p&gt;

&lt;p&gt;[[&lt;a href=&quot;/2026/06/23/self-help-books-review.html&quot;&gt;2026-06-23-self-help-books-review&lt;/a&gt;]]&lt;/p&gt;

&lt;p&gt;I think this book is one of the best I have read so far. It
isn’t a single methodology book like “bullet journal” or “Pomodoro
technique”. This book contains a few methodologies combined, all
under the umbrella of having a experimental mindset:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;It suggests having personal pacts, and review them like
“Triggers” or “The one thing”&lt;/li&gt;
  &lt;li&gt;It touches on purpose in a concise and direct way, similar to
“the purpose code” [[&lt;a href=&quot;/2025/03/20/the-happiness-lab-how-to-find-your-purpose.html&quot;&gt;2025-03-20-the-happiness-lab-how-to-find-your-purpose&lt;/a&gt;]]&lt;/li&gt;
  &lt;li&gt;The chapters on time and legacy contain similar in ideas to
“Four thousand weeks”&lt;/li&gt;
  &lt;li&gt;The social flow and learning in public quotes “Flow”, also it
reminded me of some ideas on general openness&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is science friendly, like tiny habits, but it feels less like
“hacking yourself”. It is as broad on goals as “Building a second
brain”, but I think it is more cogent. It is told as a personal
story at times, but without leaning too much on it (like “learning
systems thinking” [[&lt;a href=&quot;/2025/11/17/systems-thinking-review.html&quot;&gt;2025-11-17-systems-thinking-review&lt;/a&gt;]]).&lt;/p&gt;

&lt;p&gt;I would recommend it to anyone that feels like they have reached a
dead end and are looking for a self help book.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;*&lt;a href=&quot;/a/tag/book/&quot;&gt;#book&lt;/a&gt; &lt;a href=&quot;/a/tag/review/&quot;&gt;#review&lt;/a&gt;&lt;/p&gt;

</description>
        <pubDate>Tue, 30 Jun 2026 00:00:00 +0100</pubDate>
        <link>http://nestorarocha.com/2026/06/30/tiny-experiments-review.html</link>
        <guid isPermaLink="true">http://nestorarocha.com/2026/06/30/tiny-experiments-review.html</guid>
        
        <category>book</category>
        
        <category>review</category>
        
        
      </item>
    
      <item>
        <title>Remembering failure</title>
        <description>&lt;p&gt;Today some memories of a videogame came back. It was “little king
story” a wii game similar to pikmin with a king instead of Olimar
and workers instead of pikmins. The classical music was memorable
too, it matched the style of the game.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Little_King_Story&quot;&gt;https://en.wikipedia.org/wiki/Little_King_Story&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/pasted_img_20260629201320.jpg&quot; alt=&quot;wii game&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I haven’t played this game since 2011. I enjoyed think I finished it but I
don’t remember that much. It worked well as a distraction, as
entertainment while I was trying to start a web product.&lt;/p&gt;

&lt;p&gt;It wasn’t a good time to start a company, neither inside nor
outside. The job market wasn’t great back then. The career change
I made towards NLP didn’t work that well for me. I moved too far
from Madrid so I lost most of the people I had.&lt;/p&gt;

&lt;p&gt;Despite all of that, my family offered some support to start to
write some web services I had in mind for some time. The idea was
to use what is currently pydsl and attach a repository of
languages, DSLs and a way to connect them. A hybrid between a 
&lt;a href=&quot;https://en.wikipedia.org/wiki/Language_workbench&quot;&gt;language workbench&lt;/a&gt; and
&lt;a href=&quot;https://en.wikipedia.org/wiki/Yahoo_pipes&quot;&gt;yahoo pipes&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I had some months to see if it worked. I developed a few services,
a website for it in php and that’s about it. I didn’t do basic
market research nor found the people that would be able to help
pushing it forward. I didn’t fully implement the pipes idea (I
called them boards, but same thing) as it would have required a
long time and frontend skills I did not have.&lt;/p&gt;

&lt;p&gt;So after a few months, I gave up and released the source code and
decided to go to London and try my luck.&lt;/p&gt;

&lt;h2 id=&quot;lessons&quot;&gt;Lessons&lt;/h2&gt;

&lt;p&gt;What did I get out of it? Well, some parser knowledge, improved my
python and php a tiny bit more. Also to learn a few bits of the
bureaucracy of starting a company in Spain.&lt;/p&gt;

&lt;p&gt;More importantly, the failure of it was the big learning, although I
didn’t notice until much later. With no market iteration and no
people to support the actual work nor to collaborate, I had no
chance. I didn’t have any measurement in place other than code and
visits. It was just an idea and the hope that implementing the
idea would be enough.&lt;/p&gt;

&lt;p&gt;It was closer to a dissertation than a business idea. A mental
experiment and little more.&lt;/p&gt;

&lt;p&gt;I don’t know I have fully internalised that lesson yet. I still do
hope that coming with an idea is the best part and I apply that to
the way I write programs. I believe that getting the structure
right is the most important part of the work, which is not a common 
belief. But some of it stayed with me and there is some structure
to the way I think on projects that wasn’t there before.&lt;/p&gt;

&lt;p&gt;In hindsight, this is a very expensive way to learn which I was
privileged enough to experience.&lt;/p&gt;

&lt;h2 id=&quot;the-cycle-repeats&quot;&gt;The cycle repeats&lt;/h2&gt;

&lt;p&gt;I don’t think it is coincidence that &lt;em&gt;Little King Story&lt;/em&gt; appeared
in my mind. This moment resembles that one in many ways. A change
of career path. An environment going downwards. The temptation of
focusing on an idea as a form of getting out of it, without that
much feedback.&lt;/p&gt;

&lt;p&gt;Or simply getting distracted with a good game not to think about
any of this.&lt;/p&gt;

&lt;hr /&gt;

&lt;ul&gt;
  &lt;li&gt;tags:&lt;a href=&quot;/a/tag/job/&quot;&gt;#job&lt;/a&gt; &lt;a href=&quot;/a/tag/failure/&quot;&gt;#failure&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Mon, 29 Jun 2026 00:00:00 +0100</pubDate>
        <link>http://nestorarocha.com/2026/06/29/remembering-failure.html</link>
        <guid isPermaLink="true">http://nestorarocha.com/2026/06/29/remembering-failure.html</guid>
        
        <category>failure</category>
        
        <category>job</category>
        
        
      </item>
    
      <item>
        <title>More on 2026 job search</title>
        <description>&lt;p&gt;I recently finished the first stint of job seeking efforts. I
started gathering momentum in early may and applied for many jobs
for a few weeks, but unfortunately nothing has worked so far and I
decided not to continue while waiting for the results.&lt;/p&gt;

&lt;p&gt;Context: London jobs, remote or hybrid, around my
python/fintech experience, nothing bigger than 500 people.&lt;/p&gt;

&lt;p&gt;My strategy has been using my current experience (mostly python,
platform and infrastructure work) to get a job similar to previous
roles, aiming for a slightly lower salary than what I had.&lt;/p&gt;

&lt;p&gt;I have been quite selective and I have looked for things that were
both similar enough and I found interesting for one reason or
another.&lt;/p&gt;

&lt;h2 id=&quot;some-stats&quot;&gt;Some stats&lt;/h2&gt;

&lt;p&gt;I applied to &lt;strong&gt;14&lt;/strong&gt; roles.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;2 Initiated by recruiter, 12 by me.&lt;/li&gt;
  &lt;li&gt;I used the platform cord for around 8 roles, using regular web
search or job board search for the rest&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;10&lt;/strong&gt; (71%) were rejected or ghosted straight away.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;7&lt;/strong&gt; (50%) rejected&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;3&lt;/strong&gt; (21%) ghosted&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;strong&gt;4&lt;/strong&gt; (29%) left I got an answer. All of them I successfully
got through the screening (I am human enough after all).&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;1&lt;/strong&gt; (7%) I did not pass the assignment (rejected)&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;1&lt;/strong&gt; (7%) I did not pass the technical interview. (ghosted).&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;2&lt;/strong&gt; (14%) I got through the technical interview but I did not
pass the “fit” interview. (rejected)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;the-different-failures&quot;&gt;The different failures&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;ghosted or rejected before starting&lt;/strong&gt;  Pretty much any role
non python, in health or energys sectors. If the experience is not
relevant companies are not in the mood of figuring it out.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;assignment&lt;/strong&gt;: The main issue was that the interview prompted for
5 hours of work at most. This company relied heavily on LLMs for
all parts of the process and from the feedback they expected more
features. I don’t think I am that slow but maybe, although I
suspect that they expect LLM usage. They didn’t value the manual
process or testing that much, so I think I need to either skip
these LLM implicit roles or clarify if the time limit is with AI.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;technical interview&lt;/strong&gt; It was a tough 2 hour interview sharing
screen. The first hour, a writing code test, I got well enough to
get it implemented. But the second part, a giant code review of a
codebase that I didn’t have access to until the interview was very
difficult. I do not know what they were seeking for, as I find
unrealistic to read both the existing code and the changes at the
same time. Perhaps better communication or stress management? It
could have been that they expect LLM input too.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;company fit 1&lt;/strong&gt; I wasn’t particularly well prepared, nor I was
feeling well during the interview, but I believe that they were
looking for good leadership skills. My experience has been mostly
of support and steering with loads of coding and I don’t think
that’s where they were looking for.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;company fit 2&lt;/strong&gt; I was better prepared for this one, but even
with that I failed on a similar set of questions, although this
time hypothetical rather than personal experience. They were
looking for someone with strong coding+product and leadership
role, which again is not my direct experience (My leadership has
been more subtle in general)&lt;/p&gt;

&lt;h2 id=&quot;what-did-i-learn-and-where-do-i-go&quot;&gt;What did I learn and where do I go&lt;/h2&gt;

&lt;p&gt;I can confidently say that with the market so tight and that the
purely software developer role is gone. Right now companies are
looking for someone with very relevant experience for their stack,
combined with some other skill. I saw these subroles as
requirements on top of software skills:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;devops/infrastructure&lt;/li&gt;
  &lt;li&gt;product/leadership&lt;/li&gt;
  &lt;li&gt;LLM workflows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Anything outside being an almost perfect match in stack is a non
starter, and failing in the subrole requirements means not passing
the other stages of the interview.&lt;/p&gt;

&lt;p&gt;I also noticed that some of these companies keep the roles open
and well advertised, which means that they have a strict process
that they are happy to go through many candidates to find the
“perfect fit”.&lt;/p&gt;

&lt;p&gt;On the next steps: to widen the requirements and see what’s
outside the “similar to before” jobs. If that doesn’t work I might
try again with a more focused strategy.&lt;/p&gt;

&lt;hr /&gt;

&lt;ul&gt;
  &lt;li&gt;tags:&lt;a href=&quot;/a/tag/job/&quot;&gt;#job&lt;/a&gt; &lt;a href=&quot;/a/tag/search/&quot;&gt;#search&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Part 1 [[&lt;a href=&quot;/2026/05/15/notes-on-2026-job-market.html&quot;&gt;2026-05-15-notes-on-2026-job-market&lt;/a&gt;]]&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Fri, 26 Jun 2026 00:00:00 +0100</pubDate>
        <link>http://nestorarocha.com/2026/06/26/more-on-2026-job-search.html</link>
        <guid isPermaLink="true">http://nestorarocha.com/2026/06/26/more-on-2026-job-search.html</guid>
        
        <category>job</category>
        
        <category>search</category>
        
        
      </item>
    
      <item>
        <title>Exploring LLMs from a DSL perspective</title>
        <description>&lt;p&gt;Long time ago I wrote pydsl thinking that DSLs would, if easy
enough to make and use, be equivalent to programming languages.&lt;/p&gt;

&lt;p&gt;This turned out to be mostly wrong, as programming languages
remain the most common way to tackle business problems. Ian Cooper
wrote about different generations of programming languages and
accidental complexity of DSLs&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://ian-cooper.writeas.com/is-ai-a-silver-bullet&quot;&gt;https://ian-cooper.writeas.com/is-ai-a-silver-bullet&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I wanted to explore the transformer architecture and compare it to
DSLs.&lt;/p&gt;

&lt;h2 id=&quot;the-dslparser-architecture&quot;&gt;The DSL/parser architecture&lt;/h2&gt;

&lt;p&gt;The way I thought about it is that tiny reusable languages could
be composed easily:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/5b873745759b333bcb409250af15f23e.png&quot; alt=&quot;DSLs data flow&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Where each language would accept certain types of inputs, have
their own tokens and produce outputs. The difficulty is to write
these parsers easily and all the error handling that would come
with it.&lt;/p&gt;

&lt;h2 id=&quot;the-transformer-architecture&quot;&gt;The Transformer architecture&lt;/h2&gt;

&lt;p&gt;This is my current understanding of the transformer architecture
for a decoder only:
(read from &lt;a href=&quot;https://dev.to/pranaybathini/the-transformer-architecture-a-deep-dive-into-how-llms-actually-work-4c46&quot;&gt;https://dev.to/pranaybathini/the-transformer-architecture-a-deep-dive-into-how-llms-actually-work-4c46&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/373477098b72b889d6d7f3708987eddb.png&quot; alt=&quot;transformer data flow&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;step1&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;tokenisation: Where token is some stem, prefixes and suffixes
combination&lt;/li&gt;
  &lt;li&gt;embedding: rather than individual symbols, tokens are vectors of
hundreds or thousands of dimensions &lt;strong&gt;vector width&lt;/strong&gt;
Number of parameters: a lot of it comes from embedding layer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;step2&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Position information: A new vector &lt;strong&gt;vector width&lt;/strong&gt; per position
that combines with the embedding. It says sine and cosine wave so
maybe some FFT,,&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;step3&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Attention: the model has somewhere between 8 and 128 attention
heads. They mean grammar or meaning or similar relationships ,
each one do the following:&lt;/p&gt;

&lt;p&gt;For each (word? token?) it has a&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;query: what am I looking for&lt;/li&gt;
  &lt;li&gt;key: what do I contain (? the vector)&lt;/li&gt;
  &lt;li&gt;value: information it carries&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;all &lt;strong&gt;vector width&lt;/strong&gt;. query and key multiply to produce a score
for a pair of (word? token?)&lt;/p&gt;

&lt;p&gt;This becomes the new value (?). All of these attention heads
combine and feed into step4&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;step4&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Thinking: Feed forward network FFN. With all the outputs of step3
it creates an enriched vector with all the attention heads. There
is a bigger size vector going on and it gets compressed again.&lt;/p&gt;

&lt;h2 id=&quot;comparing-both-approaches&quot;&gt;Comparing both approaches&lt;/h2&gt;

&lt;p&gt;Compared with the LLM transformer architecture, DSLs:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;have a small number of tokens&lt;/li&gt;
  &lt;li&gt;tokens are an entity as in individual unique thing, not a
vector&lt;/li&gt;
  &lt;li&gt;The attention step is similar to context dependent grammars,
but the context is built in the grammar rules&lt;/li&gt;
  &lt;li&gt;The FFN is the production part of the parsing as in creation of
the intermediate representation or whatever output of the
compiling is. The compiler production rules are equivalent to
the expansion that happens in this step&lt;/li&gt;
  &lt;li&gt;There is no loop nor layers. In transformers 3 and 4 repeat
many times&lt;/li&gt;
  &lt;li&gt;there is the possibility of “generative” aspects in the DSL,
like enumerating all the possible accepted inputs
&lt;a href=&quot;https://codeberg.org/nesaro/pydsl/src/branch/master/pydsl/grammar/definition.py#L29&quot;&gt;https://codeberg.org/nesaro/pydsl/src/branch/master/pydsl/grammar/definition.py#L29&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Overall, the ability to automate both the tokenisation and the
parsing to produce a plausible outcome opens the door to a lot of
automation, with the trade off of lack of certainty and massive
resource consumptions.&lt;/p&gt;

&lt;p&gt;I imagine designing a calculator as an efficiency achievement,
whereas this is more like a plausible generator of output. An
automation achievement&lt;/p&gt;

&lt;hr /&gt;

&lt;ul&gt;
  &lt;li&gt;tags:&lt;a href=&quot;/a/tag/llm/&quot;&gt;#llm&lt;/a&gt; &lt;a href=&quot;/a/tag/dsl/&quot;&gt;#dsl&lt;/a&gt; &lt;a href=&quot;/a/tag/pydsl/&quot;&gt;#pydsl&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Thu, 25 Jun 2026 00:00:00 +0100</pubDate>
        <link>http://nestorarocha.com/2026/06/25/exploring-llms-from-a-dsl-perspective.html</link>
        <guid isPermaLink="true">http://nestorarocha.com/2026/06/25/exploring-llms-from-a-dsl-perspective.html</guid>
        
        <category>dsl</category>
        
        <category>llm</category>
        
        <category>pydsl</category>
        
        
      </item>
    
  </channel>
</rss>
