home.social

Search

138 results for “stag1e”

  1. EchoVault: I Built an Open-Source AI That Helps Forgotten Memories Live On


    Some of the most valuable things we own aren't expensive devices or files stored in the cloud.

    They're the stories we hear from our grandparents. The recordings we make during family gatherings. The letters we keep but rarely revisit. The little details that seem ordinary today but become priceless years later.

    And yet, these memories are surprisingly easy to lose.

    Recordings remain buried in folders. Audio files are difficult to search. Handwritten notes get separated from their context. Eventually, the people who remember these stories might no longer be around to tell them.

    For Hacktoberfest Week 4, I wanted to explore a different interpretation of Ghost in the Machine.

    What if AI could help preserve the voices, stories and memories that time might otherwise erase?

    That idea became EchoVault.

    What I Built


    EchoVault is an AI-powered memory archive designed to help people preserve, organize and rediscover personal stories.

    Instead of treating old recordings and written memories as files that simply sit on a device, EchoVault helps turn them into a searchable collection of stories.

    The workflow is simple:

    1. Upload an audio recording or written memory.
    2. Transcribe supported audio recordings.
    3. Generate a concise summary and extract useful details.
    4. Save the original material alongside its transcript and metadata.
    5. Search the archive and ask questions about the saved stories.
    6. Create a remembrance page that brings the material together in a readable format.

    The goal isn't to make AI replace the people behind these memories. It's to make their stories easier to preserve, revisit and share.

    EchoVault is about helping memories survive, not pretending that AI can bring someone back.

    Demo


    In the demonstration, I'll upload a sample recording, show how EchoVault transcribes and summarizes it, and retrieve a detail from the saved story.

    I'll also demonstrate how the original recording and its generated content remain connected, so users can verify the archive entry against its source.

    Code


    The repository contains the application source code, setup instructions, model configuration, dependencies and documentation for running EchoVault.

    The goal is to make the project reproducible so other developers can experiment with the models, improve the archive workflow or adapt it to their own use cases.

    How I Built It


    I built EchoVault around Python, Streamlit and open-source AI tools.

    The architecture separates transcription, language-model processing, storage and retrieval so that each component can be tested independently.

    1. Transcription


    For supported audio recordings, EchoVault uses OpenAI Whisper running locally to convert speech into text.

    The transcript makes a recording searchable and gives the next stage a text representation to work with.

    Transcription accuracy still depends on recording quality, accents, background noise and the languages supported by the selected model.

    2. Memory extraction


    An open-weight Gemma model processes the transcript and generates structured metadata such as a title, summary, key events and people mentioned.

    I designed this stage to distinguish the original story from AI-generated interpretations. The original transcript remains available for verification.

    3. Searchable archive


    EchoVault stores the original files and associated metadata, making it possible to revisit individual memories rather than repeatedly processing every recording.

    4. Grounded question answering


    The question-answering feature retrieves relevant material from the archive and uses it to formulate an answer.

    Rather than treating the model as an unrestricted storyteller, the application is designed to ground responses in the saved records.

    If a question cannot be answered from the available material, the system should say so instead of inventing a memory.

    5. A human-centered interface


    I used Streamlit to create an interface for uploading recordings, reviewing transcripts, exploring archived stories and generating remembrance pages.

    I wanted the experience to feel more like a digital archive than a generic chatbot.

    This part of the project taught me that building a useful AI application involves more than prompting a model. Data handling, validation, retrieval and the way users verify generated content all matter.

    Why Does Open Innovation Matter?


    For a project dealing with personal memories, the choice of AI infrastructure matters as much as the interface.

    Privacy and control


    Family recordings and personal stories can contain sensitive information.

    Running transcription and language models locally can reduce the need to send this material to external AI services. In a fully local configuration, recordings and generated content can remain on the user's device.

    This is an architectural goal, not an automatic guarantee: the complete application must be checked for external network calls, telemetry, cloud storage and other data transfers before claiming that it is fully offline.

    Freedom to experiment


    Open-weight models give developers more flexibility to choose models, change prompts, compare performance and adapt the application to their requirements.

    For EchoVault, this means being able to experiment with different transcription and language models without designing the entire product around a single proprietary AI API.

    Preservation beyond a single service


    An archive should not become inaccessible simply because a hosted service changes its pricing, API or availability.

    Keeping original recordings, transcripts and metadata in portable formats makes the collection easier to back up and migrate independently of a particular model provider.

    Making the technology accessible


    A local-first approach can reduce dependence on recurring hosted inference charges, although users still need compatible hardware, storage and electricity.

    The larger point is that useful AI tools should be adaptable and understandable, rather than locked into an infrastructure that their users cannot control.

    My Agent Session


    I used python to implement and test EchoVault.

    The session documents the decisions, experiments and debugging steps that shaped the final application.

    The Spirit of It


    The theme Ghost in the Machine made me think about how technology interacts with memory.

    A recording is only a collection of bits until someone listens to it. A transcript is only text until someone recognizes the person, place or moment behind it.

    AI cannot replace the human experience of remembering someone. It can, however, help make the material we leave behind easier to preserve and understand.

    I want EchoVault to make it easier for someone to rediscover a story they had almost forgotten, find a detail in an old recording, or bring together memories that would otherwise remain scattered across devices.

    The most meaningful result isn't an AI-generated story that sounds convincing.

    It's helping someone find a real story worth remembering.

    What's Next?


    I'd like to explore better multilingual transcription, additional document formats, richer search, exportable remembrance pages and tools for organizing large collections of recordings.

    I also want to improve source attribution so users can move directly from a generated summary or answer to the original passage that supports it.

    EchoVault began with a simple question: what if we could use open-source AI to help preserve the stories that matter to us?

    My answer is a small step toward making personal archives more accessible, searchable and useful.

    Because sometimes the most valuable thing an AI can do isn't generate something new.

    It's help us hold on to something we already have.

    devchallenge #hf26challenge

    #devchallenge #hf26challenge #software #coding #development #engineering #inclusive #community
    EchoVault: I Built an Open-Source AI That Helps Forgotten Memories Live On

  2. The order handler was accepting a negative quantity and storing it. Asked to fix that, the agent added a condition that rejects values below zero, ran the suite, reported done. The new test passed. The next invalid order still landed in the table.

    The guard existed and read correctly; it simply ran after the insert instead of before it. The test never exercised that ordering because it called the guard on its own.

    A correct check in the wrong place still fails


    Validation has one job: stop the request before any system state changes. Once a row is written, a payment is charged, a queue message is published, or an email goes out, checking the value afterward can only react to damage that already happened. Rejecting after the fact is logging a problem, not preventing one.

    The agent copied the familiar shape of a guard clause without anchoring it to where the mutation begins. Inside the handler it found the save call, then added the check a few lines below it. The condition itself was fine; the order of operations was not.

    Why the green test hid it


    The test called the validation helper directly with a negative quantity and asserted it returned a rejection. That proves the condition evaluates the number correctly. It does not prove the condition runs before the insert, because the test never reached the save flow at all.

    This is the recurring blind spot of unit testing a guard in isolation. The guard, the mutation, and the ordering between them are three separate claims, and isolating the guard tests only the first one. A negative input that reaches the actual handler reveals whether rejection truly precedes the write.

    The failure leaves no loud error


    Nothing crashes. The invalid row is stored, the response may even still look accepted, and downstream systems see a quantity they were never built to model. The bug behaves like a missing check rather than a broken one, so it survives code review: reviewers scan for a condition that rejects negatives, find it, and move on.

    It also escapes the happy-path suite, which mostly feeds valid numbers through the handler. The edge case that matters, a negative input reaching the real entry point, is the case nobody drove end to end.

    Place rejection before every side effect and prove the ordering


    When a fix adds a guard, confirm it sits at the top of the entry path, ahead of the first database write, external call, or message publish. Rejection should be the first thing that runs, before any object is built that could be handed to a persistence layer. If different writes happen in stages, each rejection must precede the stage it guards.

    Verify the ordering with a test that drives the real handler with invalid input and asserts nothing was persisted: no row in the table, no call to the external service, no published message. A guard helper tested alone cannot make that claim. The question to ask of every added check is simple: when it fires, has anything already changed?#aicode #aiagents #validation #debugging #software #coding #development #engineering #inclusive #community
    The agent added validation after the write instead of before it

  3. It’s getting hot in here – a Perimenopause evening by Bustie La Tish

    De Nieuwe Anita, Wednesday, December 9 at 08:00 PM GMT+1

    Start: 20.00. Tickets: 15,-

    It’s getting hot in here – a Perimenopause evening by Bustie La Tish

    Join Bustie La Tish for an evening of laughter, learning and letting go through storytelling, burlesque and comedy around (peri-)menopause.

    Life was a bed of roses for burlesque star Bustie La Tish, until she discovered that the sneaky symptoms spoiling her best life were caused by perimenopause. In this burlesque storytelling performance, Bustie shares her educational and hilarious journey with Dutch doctors, self-help books, period underwear, and more.

    Expect audience interaction, hilarious stories, sexy performances but also lots of sharing and learning to break this taboo!

    Whether you are going through ‘the change’ yourself or educating yourself on what’s to come for you or your loved ones, you will come out of this evening more informed and comforted.

    Bustie La Tish is a French performance artist based in Amsterdam, whose work spans performance art, burlesque, storytelling, and comedy. Bustie brings fearless authenticity to every stage — exploring themes of vulnerability, sensuality, desire, and body liberation with humour, warmth, and unapologetic sass. Beyond performing, Bustie creates shows like GOSH! (A Good Old Sexy Happening!) and Smut Slam Amsterdam (sex-positive storytelling), weaving activism and artistry into joyful events.

    offbeat.amsterdam/event/its-ge

  4. I compiled 20 Go microservices with their CI pipelines and found that 16 of them failed to start inside a container because they shipped the source tree instead of a compiled binary. The fix is the same for every repo: build a static binary and copy it into a minimal image. ## 1. Build a Production‑Ready Binary

    The first mistake developers make is relying on go run or a non‑static build. Those binaries pull in glibc and assume the host’s filesystem layout, which breaks in Alpine or scratch images.

    # Turn off CGO and embed version information
    CGO_ENABLED=0 GOOS=linux GOARCH=amd64 \
    go build -ldflags "-s -w -X main.version=$(git rev-parse --short HEAD)" \
    -o ./bin/app ./cmd/server

    markdown

    • CGO_ENABLED=0 forces a fully static binary. - -ldflags "-s -w" strips debug info, shaving megabytes. - The output path ./bin/app keeps the repo clean. Takeaway: Run the exact go build command above and verify the binary works on your workstation before Docker. ## 2. And write a Minimal Dockerfile

    Most tutorials start with FROM golang:1.22 and copy the whole repo. That bloats the image and leaves build tools in production. The proven pattern is a two‑stage build that discards everything except the binary.

    # ---- Builder Stage ----
    FROM golang:1.22-alpine AS builder
    WORKDIR /src
    COPY go.mod go.sum ./
    RUN go mod download
    COPY . . # Build static binary (same flags as above)
    RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 \
    go build -ldflags "-s -w -X main.version=$(git rev-parse --short HEAD)" \
    -o /app ./cmd/server

    # ---- Runtime Stage ----
    FROM scratch
    # Add non‑root user for security
    ARG USER=appuser
    ARG UID=10001
    RUN adduser -D -u $UID $USER
    USER $USER
    # Copy binary from builder
    COPY --from=builder /app /app
    # Expose the port your service listens on
    EXPOSE 8080
    # Start the binary
    ENTRYPOINT ["/app"]

    Key points:

    • scratch is an empty image, guaranteeing no stray files. - Adding a non‑root user prevents privilege escalation. - The EXPOSE line is optional but documents intent. Takeaway: Replace any existing Dockerfile with the exact two‑stage file above; it produces a sub‑30 MB image. ## 3. Test Locally with Docker Compose

    Skipping local verification is a common source of production pain. A one‑service docker‑compose.yml gives you a fast feedback loop.

    version: "3.9"
    services:
    api:
    build: . ports:
    - "8080:8080"
    environment:
    - LOG_LEVEL=debug
    restart: unless-stopped

    shell

    Run:

    docker compose up --build --remove-orphans

    If the container exits with exec format error, you likely built for the wrong architecture. If it starts and you can curl http://localhost:8080/health, you are ready. Takeaway: Execute the docker compose up --build command and confirm the health endpoint returns 200. ## 4. Push a Small Image to a Registry

    Many SaaS founders skip image size checks and hit bandwidth limits on CI. Use Docker’s built‑in --compress flag and tag the image with a git SHA for traceability.

    # Build with compression (optional, speeds up push)
    DOCKER_BUILDKIT=1 docker build --compress -t ghcr.io/yourorg/service:$(git rev-parse --short HEAD) . # Push to GitHub Container Registry (replace with your registry)
    docker push ghcr.io/yourorg/service:$(git rev-parse --short HEAD)

    yaml

    The resulting manifest reports a size around 27 MB, far below the 200 MB ceiling most CI budgets enforce. Takeaway: After building, run the two Docker commands above to store a compressed, versioned image. ## 5. Deploy with a One‑Line Kubernetes Manifest

    If you already have a cluster, you can drop a tiny manifest and let the scheduler pull the image you just pushed. No Helm, no Helm charts.

    apiVersion: apps/v1
    kind: Deployment
    metadata:
    name: go-service
    spec:
    replicas: 2
    selector:
    matchLabels:
    app: go-service
    template:
    metadata:
    labels:
    app: go-service
    spec:
    containers:
    - name: api
    image: ghcr.io/yourorg/service:{{git_sha}}
    ports:
    - containerPort: 8080
    resources:
    limits:
    cpu: "250m"
    memory: "128Mi"
    readinessProbe:
    httpGet:
    path: /health
    port: 8080
    initialDelaySeconds: 5
    periodSeconds: 10

    Replace {{git_sha}} with the same SHA you used for the tag. Apply with:

    kubectl apply -f k8s.yaml

    Your service is now running on two pods, each pulling a 27 MB image. Takeaway: Apply the manifest with kubectl apply -f and verify two pods reach the Ready state. ---

    Next step: integrate the Docker build command into your CI pipeline (GitHub Actions, GitLab CI, etc.) and fail the job if the image size exceeds 30 MB. That single gate guarantees every future release stays lean.

    This article was drafted with AI assistance.#go #docker #devops #microservices #software #coding #development #engineering #inclusive #community
    Dockerize a Go Microservice in Under an Hour

  5. Neun auf einen Streich… – Nine in one go…

    (English below)

    … hat das Jahr 2026 aus der Schar unserer Patenkinder in einen neuen Lebensabschnitt entlassen: entweder haben sie die Schule oder eine Berufsausbildung abgeschlossen.

    Und so stehen sie als Schulabschließer vor der Frage: „Soll ich ein Studium oder eine Berufsausbildung beginnen?“
    Um studieren zu können, bedarf es einiger Voraussetzungen, die nicht jeder Interessent erfüllt. Dann bietet sich eine Berufsausbildung an.

    Wer eine Berufsausbildung abgeschlossen hat, die in der Regel drei Jahre dauert, steht vor der Herausforderung einen festen Job zu finden. Das ist nicht einfach, denn die Zahl der Arbeitsuchenden ist groß. Aber zumindest besteht die Möglichkeit, mit Gelegenheitsjobs Geld zu verdienen, um den eigenen Lebensunterhalt zu bestreiten.

    Wir freuen uns zusammen mit den Paten, daß unsere diesjährigen Absolventen jedenfalls eine solide Grundlage von uns erhalten haben, auf der sie weiter aufbauen können.

    Da ist Adolis. Sie hat eine allgemeine technische Berufsausbildung abgeschlossen, die sie trotz ihrer körperlichen Behinderung in die Lage versetzt, im Dienstleistungsbereich arbeiten zu können.

    Alafati hat die Schule abgeschlossen und möchte eine Ausbildung als Elektriker absolvieren.

    Carine hat erfolgreich eine Ausbildung zur Schneiderin gemacht und möchte sich selbständig machen. Ihr Pate wird ihr dabei helfen.

    Amanda möchte nach erfolgreichem Schulabschluß Musik studieren. Da es jedoch nur wenige Möglichkeiten dafür in Ruanda gibt, muß sie abwarten, ob sie die strenge Aufnahmeprüfung besteht.

    Divine und Grace haben eine Friseurausbildung gemacht und werden sehr wahrscheinlich eine Anstellung finden, denn sogenannte Beauty-Salons gibt es in großer Zahl in Ruanda 🙂

    Placide konnte einen Traum verwirklichen Autoschlosser zu werden und wird sicher Arbeit finden, denn in Ruanda werden Autos solange reparirt, bsi sie buchstäblich auseinanderfallen 😉

    Johnson und Nadia haben die Schule beendet und stehen vor der Wahl, entweder eine Berufsausbildung oder ein Studium zu beginnen.

    Wir wünschen allen, daß sie erfolgreich sind und nach vollendeter Berufsausbildung Arbeit finden, um für sich und ihre künftigen Familien sorgen zu können.

    Und von unseren Lesern wünschen wir uns, daß sie unsere Arbeit mit Spenden und Ideen unterstützen!




    … the year 2026 saw a number of our sponsored children move on to a new stage in their lives: they have either finished school or completed vocational training.

    And so, as school leavers, they are faced with the question: “Should I go to university or start vocational training?”
    To be able to study at university, there are certain entry requirements that not everyone who is interested meets. In that case, vocational training is a good option.

    Anyone who has completed vocational training, which usually lasts three years, faces the challenge of finding a permanent job. This is not easy, as there are many people looking for work. But at least there is the opportunity to earn money through casual jobs to support themselves.

    Together with the mentors, we are delighted that this year’s graduates have, in any case, received a solid foundation from us on which they can continue to build.

    Take Adolis, for example. She has completed a general technical vocational training programme which, despite her physical disability, enables her to work in the service sector.

    Alafati has finished school and would like to train as an electrician.

    Carine has successfully completed her training as a dressmaker and would like to set up her own business. Her sponsor will help her with this.

    Amanda would like to study music after successfully completing her school-leaving exams. However, as there are few opportunities for this in Rwanda, she will have to wait and see whether she passes the rigorous entrance exam.

    Divine and Grace have completed a hairdressing course and are very likely to find a job, as there are plenty of so-called beauty salons in Rwanda 🙂

    Placide has realised his dream of becoming a car mechanic and is sure to find work, as in Rwanda cars are repaired until they literally fall apart 😉

    Johnson and Nadia have finished school and are faced with the choice of either starting vocational training or going to university.

    We wish them all every success and hope that, once they’ve completed their vocational training, they’ll find work so they can provide for themselves and their future families.

    And we hope that our readers will support our work with donations and ideas!

    Translated with DeepL.com (free version)

    #Africa #Afrika #anpacken #ausbildung #Bildung #Bildungspatenschaft #BildungspatenschaftsProgramm #charity #Children #dailyLabourer #deeds #donation #DritteWelt #Education #EineWelt #eltern #greeting #Hoffnung #hope #Information #job #kids #Kinder #kora #Lebensweg #nothilfe #oneWorld #PadrinazgosDeFormación #parents #Patenschaft #Ruanda #Rwanda #schicksal #scholarship #school #schule #Selbständigkeit #selbstbestimmt #Selbsthilfe #Selbstverantwortung #selbstversorger #selbstvertrauen #selfConfidence #selfConsciousnes #selfDetermined #selfHelp #selfSustaining #skills #skillsTrainig #SoutienPourLéducation #Spende #sponsorizzazione #sponsorizzazioneEducativa #sponsorship #stipendium #support #sustainability #tackle #Tagelöhner #Taten #unterricht #vocationalTraining #work #教育のためのパートナーシップ
  6. 🎄✨ Feestelijk Kerstmenu 2026: ✨🎄||🎄✨ Festive Christmas Menu 2026: ✨🎄

    Begin op Tijd met de Voorbereidingen! ✨🎄

    🎅 Een woordje vooraf van Theo-Herbots, keukenpiet in Tienen

    A warmly lit Christmas dining table welcomes guests with roast turkey, candlelight, and seasonal greenery.

    Misschien lijkt het wat vroeg om nu al een kerstmenu samen te stellen. Toch zegt een oude wijsheid: beter te vroeg dan te laat! Door nu al na te denken over uw feestmenu kunt u rustig ingrediënten verzamelen, recepten uitproberen en stress tijdens de eindejaarsperiode vermijden.

    Daarom stel ik u vandaag een volledig kerstmenu voor, van aperitief tot dessert, inclusief dranken, werkwijzen en enkele gezellige tips om van Kerstmis een onvergetelijke familieavond te maken.

    🥂 Aperitiefhapjes: Feestelijk Beginnen

    🧀 Kaaskrokantjes met vijgenconfituur

    Crisp herb crackers, fig jam, fresh figs, and white wine create an inviting rustic appetizer spread.

    Ingrediënten

    • 12 plakjes bladerdeeg
    • 100 g geitenkaas
    • Vijgenconfituur
    • 1 ei

    Werkwijze

    1. Snijd kleine vierkantjes uit het bladerdeeg.
    2. Leg een stukje geitenkaas en een beetje confituur in het midden.
    3. Vouw dicht en bestrijk met losgeklopt ei.
    4. Bak 15 minuten op 180°C.

    🍷 Bijhorende drank

    • Cava Brut
    • Prosecco
    • Alcoholvrije mousserende wijn

    🍤 Voorgerecht: Garnalencocktail Deluxe

    A beautifully layered shrimp cocktail takes center stage at an intimate candlelit dinner table.

    Ingrediënten

    • 400 g grijze garnalen
    • Gemengde sla
    • Komkommer
    • Tomaat
    • Cocktailsaus
    • Citroen

    Werkwijze

    1. Verdeel de sla over glazen of coupes.
    2. Werk af met komkommer en tomaat.
    3. Voeg de garnalen toe.
    4. Werk af met cocktailsaus en een schijfje citroen.

    🍷 Bijhorende drank

    • Droge witte wijn
    • Pinot Grigio
    • Frisse witte Bourgogne

    🐟 Tussengerecht: Romige Vissoep

    A creamy seafood chowder, fresh bread, and white wine create a warm, inviting dining scene.

    Ingrediënten

    • 500 g visafval of visbouillon
    • 1 prei
    • 1 wortel
    • 1 ui
    • 200 ml room
    • Peper en zout

    Werkwijze

    1. Stoof de groenten aan.
    2. Voeg visbouillon toe.
    3. Laat 30 minuten zacht koken.
    4. Mix en werk af met room.

    🍷 Bijhorende drank

    • Chardonnay
    • Licht houtgerijpte witte wijn

    🦃 Hoofdgerecht: Kalkoenfilet met Kroketten en Wintergroenten

    Sliced roast pork, crispy croquettes, and roasted vegetables create a festive dinner spread.

    Ingrediënten

    Voor de kalkoen

    • 1,5 kg kalkoenfilet
    • Boter
    • Tijm
    • Rozemarijn
    • Peper en zout

    Voor de groenten

    • Wortelen
    • Spruitjes
    • Pastinaak
    • Honing

    Voor het garnituur

    • Aardappelkroketten

    Werkwijze

    1. Kruid de kalkoen royaal.
    2. Bak rondom goudbruin.
    3. Laat verder garen in de oven op 180°C.
    4. Rooster de wintergroenten met een beetje honing.
    5. Bak de kroketten goudbruin.

    🍷 Bijhorende dranken

    • Rode Bordeaux
    • Merlot
    • Belgische kerstbieren voor de bierliefhebbers

    🍰 Nagerecht: Feestelijke Speculoosmousse

    A layered holiday dessert takes center stage beside a glowing Christmas tree and candle.

    Ingrediënten

    • 250 ml slagroom
    • 150 g mascarpone
    • 100 g speculooskoekjes
    • 2 eetlepels speculoospasta

    Werkwijze

    1. Klop de room stevig op.
    2. Meng mascarpone en speculoospasta.
    3. Spatel de room eronder.
    4. Verkruimel de koekjes.
    5. Maak laagjes in mooie glazen.
    6. Laat minstens 2 uur opstijven.

    ☕ Bijhorende drank

    • Koffie
    • Cappuccino
    • Dessertwijn
    • Irish Coffee voor de liefhebbers

    🎄 Gezellige Kersttips voor een Warme Sfeer

    A woman decorates by the Christmas tree while a dog rests beside the glowing fireplace.

    🕯️ Zorg voor sfeervolle verlichting

    Gebruik kaarsen, kerstlichtjes en een mooi gedekte tafel. Warm licht zorgt onmiddellijk voor gezelligheid.

    🎶 Kies rustige achtergrondmuziek

    Klassieke kerstliedjes of zachte jazzmuziek creëren een ontspannen sfeer zonder storend te zijn.

    👨‍👩‍👧‍👦 Geniet van elkaars gezelschap

    Leg smartphones even opzij en maak tijd voor gesprekken, herinneringen en leuke verhalen.

    🎁 Voorzie een kleine verrassing

    Een persoonlijk kaartje of klein attentie aan tafel wordt altijd gewaardeerd.

    📸 Maak herinneringen

    Vergeet niet enkele foto’s te nemen zodat u later nog eens kunt terugblikken op een gezellige kerstavond.

    🎅✨ Slotwoord van Theo-Herbots, keukenpiet in Tienen

    A cozy farmhouse kitchen celebrates the holidays with stew, vegetables, cookies, and warmly spiced drinks.

    Kerstmis draait niet alleen om lekker eten, maar vooral om samen zijn met familie en vrienden. Met een goede voorbereiding kunt u volop genieten van de feestdagen zonder stress in de keuken. Daarom is het helemaal niet te vroeg om nu al ideeën op te doen voor uw kerstmenu.

    Ik wens u alvast veel plezier bij de voorbereidingen en vooral een warme, gezellige en smakelijke kerstperiode toe. Want de mooiste ingrediënten van een geslaagde kerst zijn nog altijd liefde, vriendschap en gezelligheid rond de feesttafel.

    Smakelijke feestdagen en gezellige groeten uit Tienen! 🎄🍷✨

    Theo Herbots, keukenpiet in Tienen 👨‍🍳🎅📸

    🎄 Vind jij dit kerstrecept lekker?

    Heeft dit heerlijke kerstrecept je geïnspireerd? 😍✨

    📢 Deel de kerstsfeer verder

    Deel dit recept gerust met je familie, vrienden en kennissen. Zo kunnen ook zij genieten van deze feestelijke lekkernij tijdens de mooiste tijd van het jaar. 🎅🍽️

    ❤️ Samen genieten smaakt beter

    Ken je iemand die graag kookt of op zoek is naar inspiratie voor het kerstmenu? Stuur dit recept dan zeker door. Misschien delen zij het op hun beurt weer met hun familie en vrienden. 🤝🎄

    🌟 Hoe meer mensen, hoe meer kerstplezier

    Laten we samen zoveel mogelijk mensen laten genieten van deze heerlijke kerstgerechten. Bekijk ook mijn andere feestelijke recepten, tips en inspiratie voor een onvergetelijke kerst. ✨🍷🍰

    🎁 Bedankt voor je steun

    Dankjewel voor het lezen, delen en steunen van mijn blog. Samen maken we van Kerstmis een warm, gezellig en smakelijk feest voor iedereen! 🎄❤️😊

    #Kerstmis, #Kerstmenu, #Kerstrecepten, #Feestdagen, #SamenGenieten, #TheoHerbots #Tienen 🎅✨🍽️🎄🎁,

    ☕ Sluit het gezellige samenzijn in stijl af met een heerlijke kop Gourmet Black Coffee van Organo Gold.

    Geniet nog even na van alle mooie momenten, terwijl de rijke smaak en het verfijnde aroma zorgen voor een warme en smaakvolle afsluiter. ✨

    Ervaar de geur van vers gezette koffie in een handomdraai met ORGANO Gourmet Zwarte koffie. Kenners zullen de robuuste, zachte smaak, die wordt versterkt met een rijke Ganoderma lucidum waarderen. Wek je zintuigen en verrijk uw dag met een klassieke kop koffie die net zo smaakvol als verkwikkend is.

    Gourmet Black Coffee – Organo Gold

    Hier beneden kom je terecht op een plek waar mijn levenswerk samenkomt. Druk je erop, dan zie je eerst een warme inleiding tot die categorie… en daarna alle blogberichten die ik in die rubriek met liefde, tijd en ziel heb opgebouwd.

    Het is meer dan een menu. Het is een reis door mijn verhalen, mijn foto’s, mijn herinneringen, mijn inzichten — alles wat ik door de jaren heen heb gedeeld met wie hier graag vertoeft.

    Breng een Bezoek KLIK ➡️HIER ✅👍

    💌 Blijf Verbonden — Volg Onze Nieuwsbrief

    A smiling woman works on a laptop while inviting viewers to follow the newsletter from a cozy café.

    Theo‑Herbots dankt u uit de grond van zijn hart voor uw inschrijving. 

    Echt waar… dit betekent meer dan zomaar een naam op een lijst. Het betekent vertrouwen. Verbondenheid. Een stukje warmte dat jij met ons wil delen.

    En geloof me… je zal er geen spijt van krijgen. Elke nieuwsbrief wordt met zorg, liefde en een vleugje Tiense ziel samengesteld — alsof ik hem persoonlijk bij jou in de brievenbus kom steken 💌✨

    Vergeet niet om na je inschrijving even in je inbox te kijken. Klik daar op de bevestigingslink, zodat je inschrijving helemaal in orde is. Deze extra stap is speciaal ingebouwd om jou te beschermen tegen spam 💛✨

    📬 Tip: Kijk ook even in je spambox, soms verstopt het mailtje zich daar.

    Met jouw inschrijving geef je jezelf een klein cadeautje: een moment van verbinding, verhalen, foto’s, nostalgie en groeten uit Tienen die je hart raken. Elke nieuwsbrief is een beetje alsof we samen aan tafel zitten met een tas koffie ☕💛 — warm, eerlijk, menselijk.

    Wil je niets missen van onze verhalen, foto’s, inzichten en warme momenten? Schrijf je dan in op onze nieuwsbrief en ontvang regelmatig een vleugje inspiratie, een glimlach, een gedachte om mee te nemen… recht uit Tienen, recht uit ons hart. 💙✨

    Elke nieuwsbrief is een klein cadeautje:

    • 📸 een foto die raakt
    • ✍️ een tekst die blijft hangen
    • 🌿 een tip die je dag lichter maakt
    • 🤝 een gevoel van verbondenheid

    Word deel van onze groeiende community. Samen maken we het mooier.

    Vergeet niet om na je aanmelding je mail-box te checken en op die bevestigingslink te klikken. Dit is een slimme zet om jou te beschermen tegen die vervelende Spam.

    We zijn net zo anti-Spam als jij! En maak je geen zorgen, jouw gegevens worden “NIET” gedeeld met anderen!

    Voeg je bij 33K andere abonnees

    Dankjewel aan iedereen die de tijd neemt om ons te laten weten dat ons werk hen raakt. Dankjewel voor de warmte, de steun en de verbondenheid. Dankjewel dat jullie onze blog niet alleen lezen, maar ook mee vormgeven door jullie reacties.

    Samen maken we van deze plek een hartelijke, eerlijke en inspirerende online thuis. En dat is misschien wel het mooiste compliment dat we kunnen krijgen.

    Warme groet uit Tienen, Theo‑Herbots 💙📚 Blogger met Hart & Ziel

    P.S. Nu u toch hier bent…

    💬 Laat gerust een reactie achter onderaan dit bericht. Ik lees graag uw mening, ervaringen of aanvullingen.

    🌐 Neem ook eens een kijkje op mijn sociale media via de links hieronder. Daar deel ik regelmatig nieuwe inzichten, tips, handelsideeën en updates.

    🔄 Vond u dit bericht nuttig of interessant? Help dan mee om deze informatie te verspreiden en deel het verder via de sociale media-deelknoppen onderaan deze pagina.

    🙏 Alvast bedankt voor uw bezoek, uw reactie en het delen. Samen bereiken we meer mensen die er hun voordeel mee kunnen doen!

    ✨ Veel leesplezier en graag tot binnenkort! 🚀

    📱 Goed nieuws! Vanaf nu zijn wij ook bereikbaar via WhatsApp. 🎉

    Heb je een vraag over mijn blog, een blogbericht of één van de diensten die ik aanbied? Dan mag je mij gerust een WhatsApp-bericht sturen. 😊

    ⚠️ Belangrijk: dit WhatsApp-kanaal is uitsluitend bedoeld voor vragen over mijn blog en mijn diensten. Reclameboodschappen, commerciële aanbiedingen en spamberichten worden niet beantwoord.

    💬 Ik help je graag verder met al je vragen!

    Chat op WhatsApp

    Theo Herbots
    🌟📸 Blogger & Fotograaf uit Tienen 💙

    Volg ons ook op Social-Media hier beneden👇

    A cheerful creator invites viewers to follow, like, and share content in Dutch. Follow us on Social Media xfacebookinstagramyoutubepinterestlinkedinflickrtumblrvimeofoursquaremastodon #KerstmisKerstmenuKerstreceptenFeestdagenSamenGenietenTheoHerbotsTienen #TheoHerbots #TheoHerbotsFotografie #KerstmisChristmas #StepByStepChristmasMenu #TheoHerbotsTheVoiceFromTienen
  7. I write code. I did not expect to spend so much of my career thinking about
    contracts.

    Three years ago my client agreement was two paragraphs in the body of an email.
    It said what I'd build and what it cost. Every clause I've added since then went
    in because something specific went wrong, and I'd rather you learn them from a
    blog post than the way I did.

    Not legal advice — I'm a developer, not a lawyer. Have someone qualified in your
    country read anything before you rely on it.

    1. Scope, with a "not included" list


    The included list is the easy part. The not-included list is what saves you:
    logo design, copywriting, photography, hosting fees, email migration, stock
    images, ongoing maintenance.

    Clients don't read "not included" as hostile. They read it as someone who has
    done this before.

    2. Payment in three parts


    50% before work starts, 30% at design approval, 20% before launch.

    The deposit isn't a formality. It's the difference between a client who is
    committed and a client who is exploring options.

    3. The deposit is non-refundable once work begins


    You turned down other work to hold those weeks. That's what the deposit pays for.

    4. Late payment stops work


    Not "may stop work". Stops. And the timeline moves by at least the length of the
    delay — your calendar doesn't grow a free week later just because they were slow.

    5. What the client owes you, with actual dates


    Content, logo files in vector format, hosting and domain access, feedback within
    a set number of working days. Put real dates next to each one, in the proposal,
    before anyone signs.

    6. The content delay clause


    If I could keep only one clause, it would be this.

    If content is more than X days late, the project goes on hold, and the invoice
    for work completed to that point becomes due. It rejoins my schedule when I have
    room — which might be weeks later.

    This sounds harsh until the third time a project dies because nobody wrote the
    About page. Almost every stalled project I've had stalled on content, not code.

    7. Revision rounds, and a definition of "round"


    A round is one consolidated set of feedback. Five emails over three days is five
    interruptions, not one round, and if you don't define it you will be the one
    absorbing the difference.

    8. Change requests in writing, before any work


    Client asks. You reply with cost and timeline impact. They confirm. Then you
    start.

    This isn't bureaucracy, it's protection in both directions. They never get a
    surprise invoice and you never do unpaid work. Small things I still absorb
    without mentioning — the clause exists for the "while you're in there, can we
    add a booking system" requests.

    9. Silence counts as approval


    If I ask for sign-off and hear nothing for X working days after one reminder,
    that stage is approved and we move on.

    Without this, one unresponsive client freezes your schedule indefinitely and
    you have no way to restart it.

    10. Ownership transfers on final payment


    Until the last invoice clears, the work is mine. The site goes live when payment
    does.

    This is the single most effective clause for getting a final invoice paid, and
    it has never once caused an argument with a client who intended to pay.

    11. One named decision-maker


    When feedback arrives from four people who disagree with each other, someone on
    the client's side has to resolve that before it reaches you. Name that person in
    the contract.

    12. What happens if either side walks away


    They pay for work completed. Anything prepaid and not yet worked against comes
    back. Agreeing this while everyone is still friendly takes five minutes;
    agreeing it afterwards takes a lawyer.

    None of this makes you difficult to work with. In my experience it does the
    opposite — clients relax when the person building their site clearly knows how
    projects go wrong, because it suggests you've finished a few.

    What's in your contract that isn't in mine? I'm still adding to this.#freelance #webdev #career #business #software #coding #development #engineering #inclusive #community
    The contract clauses I added after three years of client websites

  8. Good morning. ☕🫖🍃

    24 October 2026

    Charlie and I spent part of the morning on the porch of my wife's little quilting shop. There was a welcome chill in the air, enough that I pulled on a sweatshirt before settling in with a Thermos of coffee. We enjoyed the quiet while waiting for the sun to climb above the trees in the east. The porch faces south, so during this time of year it catches the sunlight directly once the day gets underway.

    Charlie wandered the yard, following scents and conducting his usual patrol until he had accomplished what he came outside to do. After that, he joined me on the porch, and together we watched the neighborhood slowly come to life.

    Yesterday, we noticed a worker using a measuring wheel along the road out front. My curiosity got the better of me, so I walked over and asked what he was working on. He told me they were taking measurements for an AT&T fiber installation, which was welcome news. I've been hoping for AT&T Fiber to make its way here for several years, but until now it hasn't been available.

    At the moment, I have AT&T Internet Air, a cellular-based internet service that works pretty well most of the time, but fiber should be a significant upgrade. I even let the crew stage several large rolls of fiber at the southeast corner of my property. They're supposed to begin work on Monday.

    Now I'm debating whether to go with 1-gig service or splurge on the 5-gig plan. Honestly, 5 gigabits per second is probably far more than I need. But I've always been a bit of a computer geek, and there's something alluring about having more power than you can realistically use. It's kind of like needing nothing more than a sensible four-cylinder sedan but driving off the lot with a big Hemi under the hood instead.

    "The sun shines not on us but in us."
    ― John Muir

    "The price of anything is the amount of life you exchange for it." ― Henry David Thoreau

    #photo #photography #wildlife #nature #morning #seascape #technology #computers

  9. AI can generate a financial model that looks coherent, contains valid formulas, and produces a plausible result while still being wrong in ways that matter.

    A formula can reference the wrong cell. A cost assumption can be expressed in the wrong unit. A revenue schedule can omit a phase. A model can calculate correctly from an unsupported market assumption.

    These are different failure modes, and they need different controls. For real estate feasibility models, the objective should not be to ask whether an AI-generated workbook looks correct. It should be to establish which properties can be tested automatically, which assumptions require evidence, and which decisions must remain with a qualified human reviewer.

    A useful validation architecture has five layers:

    1. Structural validation
    2. Deterministic calculation checks
    3. Domain and consistency checks
    4. Evidence and provenance checks
    5. Human review and approval

    No single layer is sufficient.

    1. Separate the output from the evidence


    Consider a hypothetical development model with the following inputs:

    • Site area and developable area
    • Permitted gross floor area
    • Unit mix or lettable area
    • Revenue assumptions
    • Construction and other development costs
    • Financing assumptions
    • Development programme
    • Exit assumptions

    The model calculates development costs, revenue, cash flows, residual land value (RLV), and potentially internal rate of return (IRR).

    For example, a model might calculate an RLV of £4 million. That output can be mathematically consistent with the workbook and still be commercially misleading if the revenue assumptions are unsupported or the construction cost basis is outdated. Validation therefore needs to test both the calculation and the justification for its inputs.

    2. Layer one: validate the structure before the numbers


    Before reviewing financial logic, validate the shape of the generated output. If an AI system is expected to return structured data before creating a workbook, define an explicit contract. JSON Schema is one established option for specifying required fields, data types, and constraints.

    See the JSON Schema getting-started guide.
    A simplified model input contract might look like this:
    {
    "project_id": "DEMO-001",
    "currency": "GBP",
    "site_area_sqm": 5000,
    "gross_floor_area_sqm": 12000,
    "construction_cost_per_sqm": 1800
    }
    This is illustrative data, not a market benchmark or a recommendation for a production schema.

    A structural validator could check that:

    • Required fields are present.
    • Numeric values are actually numeric.
    • Areas and costs use declared units.
    • Currency is explicitly identified.
    • Values fall within defined technical bounds.
    • Unexpected fields are rejected or handled deliberately.
    • Missing values are not silently replaced with zero.

    The last point is important. Zero and unknown are not equivalent. If a finance rate is missing, substituting zero can make a model appear more profitable. A missing value should normally trigger a validation error or an explicit unresolved status.

    Structural validation establishes that the model can be interpreted. It does not establish that the model is economically sensible.

    3. Layer two: use deterministic checks for deterministic rules


    Rules that can be expressed precisely should not depend on an LLM's judgment. For example, if a model defines construction cost as gross floor area multiplied by construction cost per square metre, the expected calculation is:

    \text{GFA}
    \times
    \text{Cost per sqm}
    ]
    For the hypothetical inputs above:
    [
    12{,}000 \times £1{,}800 = £21{,}600{,}000
    ]
    A deterministic test can independently calculate the expected result and compare it with the workbook output.
    from decimal import Decimal

    gfa_sqm = Decimal("12000")
    cost_per_sqm = Decimal("1800")
    reported_cost = Decimal("21600000")

    expected_cost = gfa_sqm * cost_per_sqm

    assert expected_cost == reported_cost

    This test checks arithmetic for the stated formula. It does not establish that the GFA is permitted, that the cost rate is appropriate, or that the formula captures every relevant cost.

    A production implementation should also define tolerances where appropriate, particularly when comparing rounded spreadsheet values or calculations involving floating-point numbers.

    Other deterministic checks might include:
    Revenue equals the sum of its components.

    • Total costs reconcile to their component schedules.
    • Cash flow totals reconcile across periods.
    • Unit counts and areas reconcile between schedules.
    • The reported output matches an independently calculated result.
    • A sensitivity case actually changes the intended input.
    • Required formula cells are not unexpectedly blank or replaced by constants.

    Where possible, use independent calculations rather than simply checking that a formula cell contains a formula. A formula can exist and still be wrong.

    4. Layer three: validate model relationships


    Many serious errors are not syntax errors or arithmetic errors. They are inconsistencies between parts of the model.

    Suppose a development model contains:

    • 120 residential units in the unit schedule
    • 116 units in the sales schedule
    • Revenue calculated using the sales schedule
    • Construction costs calculated using the unit schedule

    Every formula may evaluate successfully, but the workbook contains a discrepancy that needs resolution.

    Domain-level checks can flag conditions such as:

    • Unit counts that differ across schedules.
    • Areas that exceed a declared model constraint.
    • Revenue periods that do not align with the programme.
    • Cost totals that exclude a populated cost category.
    • An exit value that uses an inconsistent timing assumption.
    • A sensitivity scenario that changes revenue but leaves dependent calculations unchanged.
    • An IRR calculation using a cash-flow range that omits a period.

    These checks should be encoded as explicit rules wherever the intended relationship is known.

    Some rules require context. For example, whether a particular cost should be included in a development budget depends on the model's scope and conventions. A validator should not impose a universal rule where none exists.

    Instead, it should identify the relevant condition, record the rule being applied, and send ambiguous cases for review.

    5. Layer four: validate the provenance of assumptions


    A financial model can pass every arithmetic test and still fail as an analytical tool.

    The reason is straightforward: calculations cannot establish the truth of their inputs.

    For every material assumption, a validation system should try to preserve:

    • The value and unit.
    • The source or origin of the value.
    • The source's date and relevant data period.
    • The geography and asset type, where applicable.
    • The transformation from source evidence to model assumption.
    • Any manual adjustment made by the analyst.
    • The model locations that depend on the assumption.

    Consider a construction cost assumption of £1,800 per square metre. A validator might confirm that the figure is numeric, the unit is recorded, and the workbook uses it consistently. Those checks do not establish whether the figure is suitable for the location, asset type, specification, and cost period. That question requires appropriate evidence and professional interpretation.

    An LLM may help extract candidate assumptions from documents or explain how a value is used in a workbook. The extracted result should still be checked against its source, and the resulting assumption should remain distinguishable from the underlying evidence.
    A useful principle is:
    Traceability makes an assumption inspectable. It does not make the assumption correct.

    6. Layer five: make human review a defined state transition


    Human review should not be an informal final glance after an automated process has already treated the model as complete.

    A practical workflow can represent validation explicitly:

    GENERATED
    |
    v
    STRUCTURE_CHECKED
    |
    v
    CALCULATIONS_CHECKED
    |
    v
    DOMAIN_CHECKED
    |
    v
    EVIDENCE_REVIEWED
    |
    v
    HUMAN_APPROVAL_REQUIRED
    |
    +----> APPROVED FOR THE DEFINED PURPOSE
    |
    +----> RETURNED FOR CORRECTION
    |
    +----> BLOCKED: UNRESOLVED ISSUE

    The states are illustrative, but the distinction matters. A successful automated test should not automatically mean that a model is approved. Approval should be scoped to a defined version of the workbook, its assumptions, its evidence, and its intended use.
    A reviewer should be able to see:

    1. What was generated.
    2. Which automated checks passed.
    3. Which checks failed or were skipped.
    4. Which assumptions lack adequate evidence.
    5. What changed after a correction.
    6. Who approved the model and for what purpose.

    If a material input or formula changes after approval, the system should identify which checks need to run again and whether the earlier approval remains valid. This is where versioning and change tracking become part of model governance rather than administrative overhead.

    7. Design the exception path before the success path


    Validation is often designed around a clean example: the model is generated, every check passes, and the user receives the output. Production systems need to handle less convenient outcomes.

    A failed check should produce actionable information. “Validation failed” is less useful than “The unit count in the sales schedule differs from the unit schedule; review the linked inputs before approving revenue.”

    Similarly, a warning should not disappear simply because a later stage of the workflow succeeds. For auditability, preserve the check identifier, the model version, the result, the relevant evidence, and the resolution.

    8. Measure validation quality without inventing an accuracy score


    A single “model accuracy” percentage can hide important distinctions. A workbook might pass every arithmetic test while containing several unsupported assumptions. Another may contain a harmless formatting issue but have fully reconciled calculations and well-documented inputs.

    A more useful validation report separates categories:

    • Structural checks passed or failed.
    • Deterministic calculation checks passed or failed.
    • Domain checks passed, failed, or were not applicable.
    • Assumptions with verified, missing, or conflicting evidence.
    • Open exceptions and their severity.
    • Human review status.
    • The scope and version of the approved output.

    If the system is evaluated over time, track false negatives and false positives for individual validation rules against a reviewed test set. Record the test cases, expected outcomes, rule versions, and known limitations.

    Do not interpret a high pass rate as proof that the model is correct. It may simply mean that the checks cover only a narrow set of failure modes.

    The purpose of validation is to make known risks visible and testable, not to manufacture certainty.

    9. A practical implementation sequence


    A team introducing validation around AI-generated financial models does not need to automate every review step at once.

    A sensible sequence is:

    1. Define the contract. Specify the required inputs, output fields, units, and missing-value behaviour.
    2. Write deterministic tests. Start with totals, reconciliations, formula ranges, and independent calculations.
    3. Add domain checks. Encode known cross-schedule relationships and clearly defined constraints.
    4. Track provenance. Associate material assumptions with sources, dates, units, and transformations.
    5. Introduce exception handling. Make failures explicit and prevent unresolved material issues from being silently treated as passed.
    6. Define human approval. Record the reviewer, workbook version, purpose, and outstanding qualifications.
    7. Build a regression suite. Retain representative valid and invalid examples and rerun the checks when the generation logic or validation rules change.

    The test suite should include deliberate failures, not only successful examples. Examples might include missing finance assumptions, inconsistent unit counts, a formula referencing the wrong period, and a source whose geography does not match the project.

    This helps test whether the validation process detects the intended problem rather than merely accepting a plausible-looking output.

    Conclusion


    Human-in-the-loop validation is not a person checking an AI result after the important work is finished. It is a system design in which deterministic rules handle deterministic questions, domain checks expose inconsistencies, evidence is kept separate from assumptions, and a human reviewer remains accountable for unresolved judgments.

    For financial modelling, that distinction is material. A workbook can be well-formed without being economically sound, mathematically consistent without being supported by market evidence, and ready for review without being ready for a decision.

    The objective is not to make every AI-generated model look trustworthy. It is to make the model's logic, assumptions, limitations, and unresolved issues sufficiently visible that a professional can challenge it before relying on the result.#feasibility #realestate #ai #financial #software #coding #development #engineering #inclusive #community
    Human-in-the-Loop Validation for AI-Generated Financial Models

  10. Charmy’s Army in “DEE SEAST – The Hell of the Ball” – Part 3: Blue Vests and Brown Bananas

    <<< Previous COMIC strip NEXT COMIC STRIP >>>

    In the third installment of our saga, panic reaches a fever pitch before colliding directly with mundane retail logistics. Convinced that Walmart’s customer service desk has instituted a terrifying new policy for processing refunds, the ponytail girl spiraled into sheer dread: will returning a defective toaster get her tossed into a holding pen to be devoured by domesticated ghouls? Thankfully, the blonde clears the air. Dee isn’t eating dissatisfied shoppers; she works in the meat department devouring the expired cuts. She isn’t a mindless trash can, either—as corporate HR would insist, she is a proud “Waste Management Facilitator.”

    The fluorescent lights of the retail district buzzed overhead like a hive of mechanical hornets. The ponytail girl stood dead in the center of the sidewalk, completely frozen in terror, clutching both hands to her face. Her eyes were practically the size of saucers, and her breathing sounded like a bellows working overtime.

    “I bought a set of non-stick sauté pans three weeks ago,” she whispered, her voice trembling with sheer, unadulterated existential dread. “The coating is already flaking off near the handle. I have the receipt in my purse. I was literally planning to go to Customer Care this afternoon. But now? Now I know the truth! They’re going to look at my receipt, see that the packaging is torn, hit a discreet red button under the desk, and drop me down a trapdoor into Dee’s feeding pit!”

    The blonde stared at her friend for three long seconds, an expression of profound exhaustion settling across her features. She pinched the bridge of her nose and let out a deep, shuddering sigh that blew a stray blonde lock out of her eyes.

    “Have you ever, in your entire life, heard of a big-box store feeding actual human customers to an employee?” the blonde asked flatly. “Do you realize the liability insurance premiums on that alone? The Occupational Safety and Health Administration would have field inspectors crawling through the air ducts within forty-eight hours. The paperwork would take decades.”

    “Corporations do terrible things to protect their quarterly profit margins!” the ponytail girl insisted, gesticulating wildly toward the towering blue sign visible above the tree line. “Think about it! Customer returns cost money! Salvage freight costs money! If you replace the return desk with an apex predator from beyond the grave, refund requests drop to absolute zero overnight! It’s the ultimate cost-cutting measure!”

    “She’s in the meat department, you absolute lunatic,” the blonde barked, grabbing her friend by the arm and dragging her along the pavement. “She doesn’t eat dissatisfied patrons who lost their receipt for a shower curtain. She eats the brown ground chuck and the discount chicken thighs that have been sitting in the display cooler forty-eight hours past their sell-by date!”

    The ponytail girl blinked once. Twice. Her frantic breathing slowed down, though the look of absolute disgust remained firmly plastered across her face. “Wait… what?”

    “You heard Charmy earlier,” the blonde continued, shaking her head. “Food waste is one of the biggest logistical hurdles in supermarket management. Stores throw away literal tons of spoiled produce, dented cans, and graying beef every single calendar year. Landfills charge dumping fees. Commercial composters have strict guidelines. But an undead post-human? Their digestive systems—or whatever remaining chemical soup passes for an internal organ—can neutralize bacteria that would put a vulture into an intensive care unit.”

    “So she’s a garbage disposal,” the ponytail girl summarized, wrinkling her nose until her freckles scrunched into a tight knot. “A glorified, walking, rotting kitchen sink drain with bangs.”

    “Charmy said she prefers the title Waste Management Facilitator,” the blonde corrected with an ironic smirk. “Corporate America doesn’t hire monsters; they hire operational specialists. They probably gave her an orientation badge, a five-minute video on slips, trips, and falls, and a designated break room in the refrigerated storage annex so she doesn’t scare the bakery associates.”

    Across the street, Charmy and Dee had paused outside a small convenience store. Dee was leaning against a lamppost, her head tilted at a precarious angle that suggested her neck vertebrae were merely suggestive guidelines. A passing delivery driver glanced at her, double-took, and quickly crossed the street with an expression of profound confusion, but nobody screamed. Nobody dialed the national guard. The world had simply absorbed the unthinkable and filed it away under routine municipal oddities.

    “I don’t know what’s worse,” the ponytail girl muttered, watching Dee attempt to scratch her shoulder and nearly dislocating her collarbone in the process. “The idea that the zombie apocalypse ended with our society almost being overrun, or the idea that it ended with the survivors realizing zombies could be exploited for unpaid sanitation labor.”

    “Welcome to late-stage capitalism,” the blonde replied with a dry chuckle. “If a catastrophic virus wipes out twenty percent of the population, the remaining eighty percent won’t mourn; they’ll just figure out how to put the fallen to work clearing out the dairy aisle. But hey, look at the bright side: at least Dee is earning an honest living. It’s more than half the guys you’ve dated this year can say.”

    “That is a low blow and completely uncalled for,” the ponytail girl grumbled, though she couldn’t suppress a faint, cynical grin. “At least my exes showered once a week. Dee looks like she just crawled out of an abandoned septic tank behind a haunted waterpark.”

    “True,” the blonde agreed, watching as Charmy gently handed Dee a small bottle of hand sanitizer, which she promptly attempted to drink before Charmy calmly redirected it to her palms. “She’s definitely rough around the edges. But that brings up an even more pressing dilemma: with Halloween coming up, what does an integrated undead citizen do for social life? And more importantly… what does this mean for the town dance?”

    TO BE CONTINUED….

    Rate this:

    #books #fantasy #fiction #shortStory #writing
  11. Tokens Over Hires

    In the middle of September I ran ccusage against every Claude Code session on my laptop since May. It walks the local logs, counts the tokens, and prices them at what the API would have charged. I expected a big number. What came back was about twenty billion tokens and just under fourteen thousand dollars, across every project I’d touched in four months, with most of it going to Pepper, which is now open for signups, so go check it out. Nineteen billion of those tokens were cached reads.

    I sat with that for a minute. Fourteen thousand dollars is real money. At my current pace it works out to roughly thirty thousand a year. I could triple it and spend a hundred thousand dollars a year on tokens, and that still isn’t one engineer. In exchange, Chris and I have shipped more code than I’ve shipped in any stretch of my career. I wrote in September that the two of us merged 657 pull requests in our first thirty days with a budget instead of a platform team. When I put the ccusage number in those terms on a panel, it came to about a dollar fifty a pull request.

    That number is what my laptop would have cost at API prices, and it isn’t what we actually pay. Here’s the whole bill for both of us. Two Codex subscriptions, one each, are $200 a month. Anthropic is $550 a month: a Max plan for me and Chris, plus two Vycari team seats, one for Chris and one that runs our automation. I have an Ollama subscription at $200 a year. Greptile is about $1,500 a month. All in, that’s a little under $2,300 a month, or about $28,000 a year, for both founders and every pipeline we run. It still isn’t one engineer.

    The obvious conclusion is the one a friend reached when he heard the figure: if code is that cheap, just get more tokens. I thought so too, for about a day. Then I looked at what was actually slowing us down, and the token budget wasn’t on the list.

    The Constraint Is Attention

    Every agent I run needs things from me that tokens can’t buy. It needs a plan approved before it starts. It needs its pull request read when it finishes. When it hits something it can’t decide, it escalates, and somebody has to be there to answer. None of those steps is expensive on its own. The problem is what happens when I run enough agents that the steps overlap.

    When I run too many agents, the cost goes up a little and the risk goes up a lot. The biggest thing that’s slipped past us so far was how we managed database connections. It got out of hand, a little at a time, while my attention was on other pull requests, and eventually it caused an outage. Chris had to roll forward while I was out of town, and I spent the following week building a proper database abstraction layer. He put it more bluntly than I would have: the thing that kills us is splitting our attention. That’s when stuff slips through.

    When people ask how we decide what to spend, I give them the order. Optimize for human time, because that’s the scarcest thing we have. Then money, because that’s the second scarcest. Then everything around agent time. “I can waste agent time all day. I don’t care.”

    So the number that limits us is how many agents one person can supervise well at the same time. I don’t have a precise figure for that ceiling. I know I’ve been over it, because I can feel the difference between a day when every pull request got a real read and a day when I was skimming to keep up.

    Another friend told me recently about engineers at his company running up bills in the thousands to build simple internal copies of SaaS tools. His reluctant guess was that they just aren’t as good at using agents yet, and that it’s a skill people have to develop. I don’t know what they’re doing differently. It doesn’t sound like token maxxing, which I’ve never really understood either. I’d love to sit with engineers who run up giant bills and just watch. My guess is they’re using the agents inefficiently, and that what’s missing is supervision, which a bigger budget won’t fix.

    Building for More Agents per Person

    Almost everything I’ve built since the summer has been an attempt to raise that ceiling, and almost none of it has been about spending less.

    The pipeline I described in The Agent That Never Merges is the first piece. Agents open pull requests continuously and never merge them, which means the supervision cost per pull request is bounded at one careful read. The pipeline absorbs the rest: triage, planning, the first round of review comments, the retries. I only see the work once it’s in a state worth my attention.

    The second piece is where the work lives. I wrote about pulling Pepper apart into small, bounded repositories to keep CI fast and give agents less to load. It mattered just as much for my attention. An agent working in a repository with one job produces a pull request I can evaluate in one sitting.

    We’re up to fourteen repositories now. Last week I moved our iOS app out of the monorepo into its own. That was 150,000 lines of code, and nobody noticed except Chris, who had to wait a day to land his next batch of iOS changes. Agents make refactors that size easy. Having the CLI and the iOS client in their own repositories also forces us to keep good API definitions between the server and its clients.

    The third piece is delegation inside the agent layer itself. I run two Claude Opus 5.5 orchestrators on medium effort. One is the UTL, for uber tech lead, and its job is to spawn subagents that build features. The other is what I call the focused worker, and its job is working with me. It catches the manual tasks that come out of the UTL’s pull requests and keeps them in a ledger. Then we work through them together: systems changes, bringing up new platforms, migrating data, anything that needs my level of access and oversight. Everything else goes to a subagent under the UTL, Opus for design docs and code reviews, Sonnet for implementing a feature from a design doc. Every one of these agents can consult a model a tier above it as an advisor, and they all share a wiki for notes.

    Anthropic is now advertising much the same pattern with Claude Projects, and I’m happy to see others arriving at the same answer. Chris has been building a loop that babysits open pull requests through review until they score well enough to be worth a human’s time. Each layer like that turns a job I used to do by hand into something I check. The ceiling goes up one delegated task at a time.

    The Token Budget Was the Easy Problem

    There was a week in September when the meter really was the constraint. We ran through our free credits and paid about $120 in overage. Then AutoDev ate the whole Vycari quota, and I did server cleanup by hand because I couldn’t do anything else.

    Most of that was self-inflicted. I’d started with Fable as the orchestrator, with no cap on context, and burned a week’s quota in three days. The setup above fixed it. The orchestrators run on medium effort, and the cheaper model does the implementing. Opus answers the reviews because Sonnet is too literal about them, and a literal reading turns two review cycles into twelve. Every agent auto-compacts at 200K tokens, because Anthropic charges more for context past that point. With that setup, and the work spread across parallel sessions, I find it hard to spend all of my quota. My goal now is to hit 99% of it every week just before it resets. I keep a list of research projects, and if I have quota left 24 hours before the reset, I spin one up. That isn’t the same as maxing out tokens. I’m not trying to use as many as possible. I’m trying to use all the ones I’ve already paid for.

    There’s also a second account on the same machine. Claude Code reads a CLAUDE_CONFIG_DIR environment variable, so two shells with two config directories give you two accounts side by side. The second one runs the AutoDev and code review pipelines, and those use up its quota every week, so it isn’t a fallback for my own sessions. When I do run short, I supplement with other labs’ plans. Every one of those fixes took an afternoon or less. None of the supervision problems above has had an afternoon fix.

    Where the Money Actually Goes

    While I had the numbers in front of me, I looked at where development spend actually lands, because it isn’t where I expected either.

    Development tokens currently run about ten times what the product itself consumes, even with real people using it. Building the thing costs more than running it. That won’t last. The feedback from our private beta has been really good, and we now open Pepper to a limited number of new signups every day, so product usage is rising quickly.

    Most of what we actually pay goes to code review. Subscriptions are the cheap way to buy tokens if you’re willing to hit limits, so they’re the smaller line. Greptile reviews every pull request we open, and at about $1,500 a month it’s our biggest single expense. We both think it’s worth it, because it’s the layer that lets the never-merge pipeline run without me reading every first draft.

    In October I tested that. I spent a few days building a cheaper reviewer to replace it. I came out the other side saying, “I think we should just pay for it because I can’t do it cheaper.” What I could change was how often we call it. The agents kept asking for a re-review before they’d fixed anything. Because every repository shares a common dev environment, the fix went in once: our pull-request skill now has agents run /simplify and then /code-review before they’re allowed to open a pull request. On many of our repositories, our own reviewer also does the first round and only then calls Greptile. My goal is a pipeline where Greptile’s reviews come back with nothing to say. We’re not there yet, but we get a little better every week.

    I’d rather pay for review than have a second person do it, and the reason isn’t salary. The person would need supervising too, because review is a job I’d have to check, not one I can hand off.

    What a Hire Is For Now

    Five years ago, if I’d been getting a product like this ready for market, I’d have been hiring twenty to fifty engineers. The work would have needed that many hands, and most of what they’d have done was write code. Today the code is the cheap part. If I bring someone in to write code, I’ve added a person who needs plans approved and pull requests read, which is the exact resource I’m short on. A hire whose job is output adds coordination faster than it adds capacity.

    I said on a podcast that came out last week that the code I’ve written would have cost about fifteen thousand dollars at API prices, and that I couldn’t hire engineers for that money. That’s true. The engineers I’d still want are a different kind from the ones I hired at Google. We need a few more people who can herd agents, not fifty.

    The engineering hire that adds capacity is a different shape. It’s someone who can own a bounded service whole. Here’s the interface, here’s everything it needs to do, let me know when it’s done. That person brings their own supervision. They run their own agents, read their own pull requests, and answer their own escalations, and the only thing that crosses the boundary between us is the contract. Supervision divides along the interface instead of piling up on one person. That’s a tech lead’s job, and it’s the only kind of engineering hire I can see that raises the ceiling instead of lengthening the queue.

    That raises a fair question about how anyone grows into that job now, which I tried to answer in The Questions Are the Job. The other advice I give is to work on open source. I’ve met people who showed they could work really efficiently with agents through open source projects, Gemini CLI in particular, and some of them ended up being hired onto my teams. Open source has its own problems right now. But if you show up as a thoughtful engineer with features or bug fixes that are well reviewed, well tested, and bring value to the project, I think you’ll be welcome. That’s one of the reasons I decided to open source the Pepper CLI.

    The first hire probably isn’t an engineer at all. I’ve said this a few times now, including on stage at a panel in September. Neither Chris nor I are go-to-market people, and I may hire one before I hire another engineer. I can create piles and piles of code, even relatively good code. What I can’t do is agentically acquire customers. (Did I mention that Pepper is open for signups now?) Someone in marketing came up after the panel and told me I’d validated her existence.

    The Third Trend

    I’ve watched this happen twice before. Open source developer tooling made it so a small team didn’t need to buy or build its own compilers, databases, and frameworks. Cloud infrastructure made it so that team didn’t need to own hardware or a data center. Each time, the number of people you needed to start something real dropped, and the skills that mattered shifted toward the people who understood systems well enough to compose what was suddenly free.

    Agentic tools are the third one. Anyone with a good idea can now get from concept to production on a budget that would have been a rounding error in a Google planning cycle. But the constraint didn’t vanish. It moved, the same way it did the last two times, toward the people who understand systems design well enough to drive the agents and notice when something has slipped through. I wrote a year ago that management skills were going to carry over to working with agents. I didn’t expect to be proving it with a two-person org chart and fourteen thousand dollars of tokens.

    This isn’t only a small-company problem. At Google it was hard to get more than a few changes in a day, because each one waited on code review. I’ve talked to engineers there who now do all their work in experimental directories that don’t require review, then port it back to their team’s repository at a pace the review process can keep up with. That’s what happens when you don’t manage for human attention. Productive people spend their cycles waiting on the process.

    When other companies ask me what to change, my answer has become: drive until human attention is the scarce resource, then build for that. If you’re reading your own ccusage number and wondering whether the answer is more tokens, look at where your attention went first. For us the answer has been more interfaces. Those are the places where one person’s supervision ends and another’s begins, or where an agent takes over a job one of us used to do by hand.

    #Agents #AI #Developer #Startups
  12. *Manchester dates* for The Crucified Silence – Sunday November 22nd – Irish World Heritage Centre. 6pm.

    “A story anyone can relate to…” — Irish Independent

    Click here to secure your ticket now!

    About

    Following acclaimed performances in Athlone, Castlebar, Ballinrobe and Galway, The Crucified Silence comes to Manchester on Sunday 22nd November at 6pm, bringing a distinctive voice from the West of Ireland to the iconic Irish World Heritage Centre.

    Hilarious, heartbreaking and brimming with dark Irish humour, The Crucified Silence is a compelling one-man play written and performed by acclaimed Irish playwright Mick Donnellan. Set in Ballinrobe, Co. Mayo, the story follows Joe, a local guard who has crossed a line after a volatile altercation with his superintendent. As he drinks his way around town, he conjures vivid, nostalgic images of familiar landmarks and meeting places, including The Bowers walk, Art O’Neill’s Bar and Geoff’s pub. These recollections bring his world to life, drawing audiences into a community shaped by its own rhythms, rituals and relationships.

    Yet beneath the laughter lies a deeply moving story of loneliness, loss, regret and the search for connection. Just as Joe’s sharp wit and comic observations have audiences laughing, glimpses of his troubled past reveal a more vulnerable man struggling to come to terms with the life he has lost. The result is a play that can have you laughing out loud one moment and breaking your heart the next.

    Populated by recognisable Irish characters and brought vividly to life through authentic Irish dialect, cultural nuances and a rich tradition of storytelling, the play offers a compelling glimpse into the humour, warmth and complexities of everyday life in rural Ireland. For those familiar with Irish life, there is much to recognise; for those discovering it for the first time, an opportunity to experience a distinctive culture through characters who feel wonderfully real.

    Book now

    The Venue

    A much-loved hub for Irish culture, arts and community in the North West of England, the Irish World Heritage Centre provides a fitting setting for a play that celebrates Irish storytelling while exploring experiences that transcend borders and backgrounds.

    For Manchester’s Irish community, the evening offers a powerful sense of home, evoking the people, places, humour and shared experiences that connect us to where we come from. It is also a wonderful opportunity to celebrate the strength of Irish theatre and the remarkable stories being created in Ireland and finding audiences beyond its shores.

    Universal Appeal

    Although Joe’s world may be rooted in a small town in Co. Mayo, his struggles are universal. His attempts to make sense of a life shaped by difficult choices, personal loss and fading connections will resonate with anyone, from all cultures and backgrounds, who has ever looked back on their past and wondered how things might have turned out differently.

    With minimal staging and intimate, uncompromising storytelling, the play places audiences face to face with Joe’s inner world, where humour becomes a defence against pain and silence can speak louder than words. Mick Donnellan’s powerful central performance draws audiences towards a devastating climax, balancing theatrical intensity with the feeling of a deeply personal confession.

    All are welcome to join for an evening of big laughs, poignant storytelling, heartbreaking moments and an unforgettable injection of high-quality theatre!

    Spaces limited so be sure to secure your seat as early as possible :)

    About Mick Donnellan and Truman Town

    Mick Donnellan works as a successful Playwright, Novelist and Screenwriter. Film credits include Tiger Raid adapted from Mick’s Play Radio Luxembourg. Optioned by London Film Company Dixon/Baxi/Evans, the script was developed in London and shot in Jordan. Starring Brian Gleeson, Damian Molony and Sofia Boutella, it was accepted into the Tribeca film festival (New York) and was also seen at Cannes and Edinburgh.

    The Irish Premiere was screened at the Galway Film Fleadh and you can watch the Tiger Raid trailer here.

    Mick is the author of six novels:

    The Dark Rooms

    Galway Blues

    El Niño

    Fisherman’s Blues

    The Dead Soup

    The Naked Flame

    Recent Work:

    Mick Donnellan has had two major theatre productions hit the stage in 2025.

    Outlaw Pete premiered at the Town Hall Studio, Galway in April 2025, starring Laura Hutchinson, Brian Cahill, and Carl Jones. Following its debut, the production toured to the Linenhall Arts Centre in Castlebar in May, before returning to Galway for the Galway Fringe Festival in July, where it sold out Kennedy’s Bar on Eyre Square.

    Donnellan’s second new play of 2025, Class of ’57, was produced by Athlone Little Theatre and directed by Caroline Coyle, featuring standout performances from Ellen Ryan, Brian Toolan, and Nino Magilocco.

    In December 2024, his most recent book Galway Blues was published to great acclaim. He received the Mayo Theatre Bursary through Mayo Arts Office in April the same year.

    Prior to that, he was awarded the Agility Award through the Arts Council of Ireland and his play Nally was supported by Westmeath Arts Office.

    In other theatre work, The Crucified Silence (as a short play) was chosen as part of the Scripts Ireland Play festival. After a week of intensive workshops with Playwright Eugene O’Brien, the monologue was directed by Jim Culleton (Fishamble) and performed by Aaron Monaghan. Following this, Mick took part in the Galway Theatre Development Programme, run by Andrew Flynn in conjunction with Galway’s Town Hall Theatre, which resulted in a residency at the Tyrone Guthrie Centre.

    His other plays include Sunday Morning Coming Down, Shortcut to Hallelujah, Gun Metal Grey, and Velvet Revolution.

    He is listed on the Irish theatre institute here: http://irishplayography.com/person.aspx?personid=47564

    About Truman Town:

    Truman Town Theatre exploded on to the theatrical circuit with their Play – Sunday Morning Coming Down. Written and directed by the company’s Artistic Director Mick Donnellan, it immediately sold out the Galway Town Hall Studio for five nights on the first run. Following that, the crew went on tour to Mayo, selling out Lisloughrey Lodge, Cong,The Valkenburg Niteclub, Ballinrobe and the Linenhall in Castlebar. It also enjoyed large audiences on the Main Stage on Galway’s Town Hall and went on a National Tour covering – Glor Ennis, St. John’s Listowel, Cork Arts Theatre and it sold out five nights at The New Theatre, Dublin. It was also performed by DRUID as a public reading during the Galway Arts Festival.

    Truman Town followed this phenomenal success with a second Play – Shortcut to Hallelujah. Again, written and directed by Mick Donnellan, it deals with the curse on the Mayo football team. It sold out the Town Hall Studio, went on tour to Ballinrobe and the Linenhall in Castlebar and then down to St. John’s Theatre, Listowel Co. Kerry where it was requested back to headline Friday night of Listowel Writer’s week.

    Between this, a third drama was produced as part of the Galway Theatre Festival. It was titled Gun Metal Grey.

    Shortcut to Hallelujah returned from Listowel Writer’s Week to perform on the Main Stage Galway for a wildly successful five nights after which Velvet Revolution, the fourth Truman Town production, also written by Mick Donnellan, was premiered in St. John’s Theatre, Listowel. It went on tour to Kilmallock, Kenmare and Waterville, then up to Ballinrobe, on to Galway and ran for ten days as part of the Galway Fringe. Mentioned as a Highlight of the festival by the Irish times, it was subsequently performed in Campbell’s Tavern, Cloghanover, Headford, Electric Picnic and The New Theatre, Temple Bar, Dublin.

    Radio Luxembourg, Mick’s fifth Play, was bought by a London Film Company (Dixon/Baxi/Evans) and has been adapted for the screen. The title for the movie version is “Tiger Raid”. Starring Brian Gleeson, Damian Molony and Sofia Boutella, it was accepted into the Tribeca film festival (New York) and was seen at Cannes and Edinburgh. The Irish Premiere was screened at the Galway Film Fleadh.

    Currently Mick is working on the exciting screen adaptation of Shortcut to Hallelujah with Florence Films. The screenplay is titled Sam and is based around the curse supposedly put on the Mayo Football team as they returned home as All Ireland Champions in 1951.  Drenched in Irish lyricism and modern day dark humour, the script has been met with keen interest by film producers and actors throughout the industry.

    Between writing projects, Mick has enjoyed roles as a lecturer in writing at University of Ireland and TUS Athlone.

    *

    Read more on www.mickdonnellan.com

    #books #music #news #Poetry #writing
  13. Pest control businesses manage more than inspections and treatments. Every service visit involves appointment scheduling, technician coordination, travel planning, customer communication, and recordkeeping.

    As a company grows, these administrative responsibilities become increasingly difficult to manage through spreadsheets, phone calls, and disconnected software.

    Artificial intelligence (AI) and workflow automation offer new ways to organize these processes. However, their value depends on how well they solve real operational problems.

    This article examines five areas where AI and automation can support pest control businesses, along with the technical considerations companies should evaluate before adopting new systems.

    1. Smarter Appointment Scheduling

    Traditional appointment scheduling often requires office staff to coordinate technician availability, customer preferences, service duration, and travel distances manually.

    Scheduling software can automate several parts of this process.

    For example, a scheduling system might:

    Display available appointment windows based on technician calendars.

    Assign jobs according to service area and technician availability.

    Send automated appointment confirmations.

    Notify customers when appointments change.

    Identify scheduling conflicts before bookings are finalized.

    AI-assisted scheduling can go further by analyzing historical job durations and recommending suitable appointment windows.

    However, these recommendations are only as reliable as the underlying data.

    A business with inaccurate service durations or incomplete technician availability records may still experience scheduling problems, even after introducing automation.

    Technical consideration: Look for scheduling systems that support configurable service durations, technician constraints, calendar integrations, and manual overrides.

    1. Route Optimization for Field Technicians

    Travel time is a significant operational consideration for businesses that send technicians to multiple customer locations each day.

    Basic route planning can arrange appointments geographically. More advanced optimization systems consider additional constraints, including:

    Appointment time windows

    Technician starting locations

    Estimated travel times

    Service duration

    Technician skills and availability

    Vehicle capacity or equipment requirements

    Some systems use optimization algorithms to recommend more efficient visit sequences.

    AI-based prediction may also help estimate travel times or anticipate schedule disruptions.

    Consider a technician assigned six appointments across different neighborhoods.

    A poorly organized schedule might require unnecessary backtracking. A routing system can evaluate possible visit sequences and recommend an order that better satisfies the day's constraints.

    Importantly, route optimization is not automatically AI. Many useful routing systems rely on established mathematical optimization methods rather than machine learning.

    For pest control companies, the practical question is whether the system produces workable routes while respecting real service requirements.

    1. CRM Automation and Customer Communication

    Customer relationship management (CRM) systems help businesses organize customer information, service histories, recurring treatments, and communication records.

    Automation can reduce repetitive administrative work.

    For example, a completed service appointment might trigger the following workflow:

    The technician marks the job as completed.

    The system updates the customer's service history.

    A service summary becomes available.

    The customer receives a completion notification.

    The system schedules a future reminder when appropriate.

    This workflow does not necessarily require generative AI. Many CRM platforms support rule-based automation using triggers, conditions, and actions.

    AI may provide additional capabilities, such as summarizing customer interactions or categorizing incoming service requests.

    Nevertheless, businesses should review AI-generated information before using it in sensitive customer communications or treatment documentation.

    Technical consideration: Evaluate how the CRM handles customer consent, communication preferences, recurring service records, and data access permissions.

    1. Connecting Software Through APIs and Integrations

    One of the most useful opportunities for pest control technology is connecting systems that would otherwise operate independently.

    A business might use separate applications for:

    Website inquiries

    Customer management

    Appointment scheduling

    Technician dispatch

    Invoicing and payments

    Reporting and analytics

    Without integrations, employees may need to enter the same information into multiple systems.

    Application programming interfaces (APIs) allow software applications to exchange information through defined interfaces.

    For example, an integration could connect an online booking form with a field service management platform.

    When a customer submits a booking request, the integration might create a customer record, generate a service request, and notify office staff.

    A typical architecture could look like this:

    Website Booking Form
    |
    v
    API / Integration Layer
    |
    v
    Field Service Management System
    |
    +--> Customer Record
    |
    +--> Service Request
    |
    +--> Scheduling Queue
    |
    +--> Notification Workflow

    For developers implementing these integrations, several considerations matter:

    Authentication: API access should use secure authentication mechanisms and appropriately scoped credentials.

    Validation: Incoming booking data should be checked before records are created.

    Duplicate prevention: Retry requests should not accidentally create duplicate customers or jobs.

    Error handling: Failed integrations should be logged and retried safely.

    Privacy: Customer addresses, contact details, and service records should be handled according to applicable privacy requirements.

    Before purchasing software, businesses should investigate whether the vendor offers documented APIs, webhooks, native integrations, or supported third-party automation tools.

    1. AI-Assisted Reporting and Business Analysis

    Pest control businesses generate operational data through appointments, service records, customer interactions, and invoices.

    Reporting tools can organize this information into useful business metrics.

    Examples include:

    Completed appointments per technician

    Average time spent on service visits

    Appointment cancellations

    Recurring service activity

    Travel time between appointments

    Outstanding invoices

    AI-assisted analysis may help identify patterns or generate plain-language summaries of reporting data.

    For example, a system might highlight an increase in rescheduled appointments or identify service areas with unusually long travel times.

    However, AI-generated summaries should be checked against the original records.

    A useful reporting system should allow managers to trace a recommendation or observation back to the underlying data.

    1. What Should Businesses Evaluate Before Adopting AI?

    Adding AI features does not automatically make a software platform better.

    Before investing, pest control businesses should ask several questions.

    Does the software solve a specific operational problem?

    Start with a measurable issue, such as missed appointments, repetitive data entry, or inefficient dispatching.

    Can employees understand and override automated decisions?

    Technicians and dispatchers need practical ways to correct schedules and handle unexpected circumstances.

    Does the system integrate with existing tools?

    A platform that creates additional manual data entry may undermine the intended benefits.

    How is customer information protected?

    Review data access controls, retention policies, vendor agreements, and security practices.

    How will performance be measured?

    Establish a baseline before implementation. Compare outcomes such as scheduling errors, administrative time, or travel efficiency after deployment.

    Businesses should also distinguish between genuinely useful AI capabilities and conventional automation presented with AI-focused marketing language.

    1. A Practical Implementation Approach

    For smaller pest control businesses, introducing several new systems simultaneously can create unnecessary complexity.

    A more manageable approach is to implement technology in stages.

    Stage 1: Document existing workflows. Identify how appointments, service records, and customer communications are currently handled.

    Stage 2: Select one problem to address. For example, automate appointment confirmations before attempting a complete dispatch-system replacement.

    Stage 3: Test with a limited group. Introduce the workflow to a small team and document errors, exceptions, and employee feedback.

    Stage 4: Measure results. Compare the new process against the previous workflow using consistent metrics.

    Stage 5: Expand carefully. Introduce additional integrations or AI-assisted features only when the earlier implementation is functioning reliably.

    This approach makes it easier to identify which technologies provide practical benefits.

    Conclusion

    AI and automation are expanding the options available to pest control businesses, particularly in scheduling, route planning, CRM workflows, software integrations, and reporting.

    The most effective systems are not necessarily those advertising the largest number of AI features.

    They are the systems that support reliable operations, provide useful information, integrate with existing workflows, and allow employees to remain in control of important decisions.

    For independent research into pest control software, scheduling tools, CRM platforms, and technology comparisons, explore Pest Tech Research.

    Better Technology. Stronger Pest Control.#automation #ai #software #api #coding #development #engineering #inclusive #community
    How AI and Automation Are Changing Pest Control Business Operations

  14. DATE: October 25, 2026 at 06:00AM
    SOURCE: PSYPOST.ORG

    ** Research quality varies widely from fantastic to small exploratory studies. Please check research methods when conclusions are very important to you. **
    -------------------------------------------------

    TITLE: Your body makes its own cannabis-like chemicals as you run, and neuroscience research finds they keep rising all the way to the marathon finish line, a possible clue to the runner’s high

    URL: psypost.org/your-body-makes-it

    A long run appears to keep the body’s own cannabis-like chemical messengers active for hours. New research published in BMC Medicine indicates that one of these compounds, anandamide, climbs steadily during a marathon and stays elevated 45 minutes after the finish, and that levels are also higher after ultramarathons of up to 230 kilometers. These chemical changes occurred alongside shifts in mood, such as reduced anxiety after running, although the study did not test whether one caused the other.

    The runner’s high is a state some people report during or after endurance exercise, marked by euphoria, reduced anxiety, less pain, and a sense of calm afterward. Early explanations credited endorphins, the body’s natural opioid painkillers, but endorphins are large, water-soluble molecules, and there is no convincing evidence that they cross the blood-brain barrier, the protective filter between the bloodstream and the brain, in meaningful amounts.

    Endocannabinoids offer an alternative: they are small, fat-soluble molecules made on demand from cell membranes, they can cross that barrier, and they act on the same cannabinoid receptors targeted by THC, the main psychoactive compound in cannabis. The two best studied are anandamide and 2-arachidonoylglycerol, often shortened to 2-AG.

    Laboratory experiments began supporting this shift in thinking when a 2015 animal experiment led by Johannes Fuss, the senior author of the new study, showed that wheel-running mice relied on cannabinoid receptors, rather than opioid receptors, to experience reduced anxiety and lower pain sensitivity. Human research soon followed, including a 2021 clinical trial by the same group where researchers gave participants a medication that blocked opioid receptors. The runners still reported the typical calm and euphoric sensations of a runner’s high, suggesting that endorphins were not required for those effects.

    In a 2022 systematic review, the same group found that 14 of 17 studies detected a rise in endocannabinoids after a single bout of exercise. But as the authors of the new study note, nearly all of that human research involved workouts lasting under an hour, leaving open what happens during true long-distance events.

    “Humans are capable of running for many hours, sometimes even days, and we wanted to understand what happens to the endocannabinoid system during such extraordinary endurance efforts,” lead author Michael Siebers, a psychiatrist at LVR University Hospital Essen, told PsyPost.

    “I believe that our ability to run long distances cannot be explained by anatomy alone,” Siebers explained. “We probably also need an entire orchestra of neuromodulators that reward us for sustained physical activity and help us continue running despite fatigue and discomfort. Thanks to a wonderful collaboration with researchers from Ulm and the German Sport University Cologne, we were able to investigate these processes during marathon and ultramarathon running, including distances of up to 230 kilometers.”

    To investigate these biochemical and emotional shifts under real-world conditions, Siebers and his colleagues, including senior author Johannes Fuss of the University of Duisburg-Essen and collaborators at University Hospital Ulm and the German Sport University Cologne, designed two field studies of trained endurance athletes.

    The first investigation examined 19 experienced runners, including seven women and 12 men, who completed a marathon course consisting of three 14-kilometer loops around Lake Baldeney in Essen, Germany. To establish a realistic comparison, each runner returned one to two months later to complete an identical-duration walking session along the same route at their preferred pace. Blood samples were drawn at the start, at the 14-kilometer and 28-kilometer marks, immediately after the full course (about 43 kilometers), and after a 45-minute rest period. Alongside blood draws, participants completed visual rating scales to score their current levels of euphoria, anxiety, and physical pain.

    The second investigation followed 36 athletes (16 ran 100 kilometers, 7 ran 160, and 13 ran 230) taking part in the TorTour de Ruhr, a non-stop ultramarathon in central Germany. These athletes, comprising 13 women and 23 men, provided blood samples and mood ratings before the race and shortly after crossing the finish line. In both studies, laboratory technicians measured several key lipids, including anandamide and 2-AG.

    In the marathon study, levels of anandamide rose progressively across the entire run. By the mid-race mark, anandamide was higher during running than during walking, which produced only modest changes, and it remained higher 45 minutes after the marathon ended. Running was also far more intense, with runners averaging about 83 percent of their estimated maximum heart rate, compared with about 58 percent while walking. The compound 2-AG displayed a different trajectory, showing lower levels early in the run compared to walking, but climbing during the final kilometers and staying elevated during early recovery.

    The ultramarathon runners exhibited similar biochemical patterns upon completing their races. Anandamide and 2-AG concentrations were both higher after the race across all three ultramarathon distances compared to pre-race baselines. In an exploratory comparison, post-race anandamide levels after the marathon were nearly double those seen after the ultramarathons (32.4 versus 17.1 in the study’s measurements), which the authors suggest may reflect the higher running intensity of the shorter race.

    Mood ratings also shifted during running. Marathon participants reported higher euphoria while running than while walking at several points, although at the 28-kilometer mark, a stage where runners often describe “hitting the wall,” euphoria was no longer different from walking. Anxiety ratings started slightly higher before the marathon than before the walk, then fell toward the end of the run, and pain ratings showed little change after 14 kilometers but rose markedly from 28 kilometers on. In the ultramarathon group, anxiety decreased after the race, more so at 100 and 160 kilometers than at 230, while pain rose and euphoria did not change in a statistically significant way.

    When asked afterward, only 3 of the 19 marathoners said they had experienced a runner’s high during the marathon, while 8 said they had not and 8 were unsure; among the ultramarathoners, 12 said they had and 19 said they had not.

    The findings are in line with research covered by PsyPost in 2022, which found that acute exercise consistently increased endocannabinoid levels, especially anandamide, with moderate intensity yielding stronger boosts than low intensity.

    “This is an interesting study, particularly because it’s not easy to investigate physiological responses to exercise over marathon and ultramarathon distances,” said Danielle McCartney, a research affiliate at the University of Sydney who was not involved in the study. “The key finding is that circulating concentrations of anandamide (AEA), an endocannabinoid, increased progressively throughout the marathon and were also elevated following ultramarathons of 100, 160 and 230 km.”

    “Previous studies have consistently shown that moderate-intensity running increases blood concentrations of AEA,” McCartney told PsyPost. “However, most of this research has focused on relatively short bouts of exercise (less than 60 minutes). This study fills an important gap by examining much longer running distances, and shows that increases in AEA also occur during marathon and ultramarathon running.”

    The researchers see the sustained activity as a possible clue to how humans manage hours of running.

    “One of our most important findings is that the body’s own cannabinoid system remains active even during extremely prolonged exercise,” Siebers noted. “We observed substantial increases in endocannabinoids, particularly anandamide, not only during marathon running but also after ultramarathons lasting many hours.”

    “These molecules are sometimes described as the body’s own cannabis-like substances because they act on the same cannabinoid receptor system targeted by THC,” he said. “They may contribute to the rewarding, calming, and potentially pain-modulating effects of running. From an evolutionary perspective, I find this particularly fascinating. Humans have an extraordinary capacity for endurance running, and the endocannabinoid system may be one of the biological mechanisms that make prolonged running not only physically possible but also psychologically rewarding.”

    Siebers described the shift many runners report over the course of a run.

    “At the beginning of a run, everything may feel uncomfortable,” he observed. “Your calves are aching, your back feels stiff, and every step requires some effort.”

    “But after a while, something can change,” he noted. “Your movements become smoother, running feels increasingly effortless, and you may enter a state of flow. Sometimes this develops into euphoria, while everyday worries and stress seem to fade into the background.”

    Siebers also sees potential relevance for mental health.

    “As a psychiatrist, I find this especially interesting because running can become a valuable tool for coping with stress, improving mood, and supporting mental well-being,” he added. “Of course, exercise is not a replacement for professional treatment when it is needed, but for some people, it can be an important part of their recovery and everyday life.”

    The study did not test whether runners whose anandamide rose the most felt the most euphoric or calm.

    McCartney cautioned, however, against assuming that these chemical increases directly generate the emotional sensations reported by participants. “It’s important to recognize that this study doesn’t establish that increases in AEA are responsible for the ‘runner’s high,'” she explained. “It shows that prolonged running increases blood AEA concentrations and is associated with changes in mood, including increased euphoria and reduced anxiety. While these findings are consistent with the idea that AEA contributes to the runner’s high, they don’t establish a causal relationship.”

    The TorTour de Ruhr presented extreme physical demands, requiring runners to navigate unfamiliar routes for up to 230 kilometers, often through the night and in isolation.

    “What impressed me most was witnessing what humans are capable of achieving,” Siebers recounted. “Some of our participants ran distances of up to 230 kilometers, maintaining their effort for many hours, sometimes running alone through the night on unfamiliar trails. Equally fascinating was the atmosphere among the ultramarathon runners. Despite the enormous physical demands, there was a remarkable sense of community and positivity.”

    “I was particularly struck by participants who reported very little anxiety after these extraordinary distances, even after spending hours alone in unfamiliar surroundings,” he said. “Some runners also reported surprisingly little pain despite covering distances that would seem almost unimaginable to most people. These observations make me wonder how strongly our internal neuromodulatory systems can influence the way we experience physical effort, pain, and fear.”

    Pain was still common: 29 of the 36 ultramarathoners reported pain during the race, only five reported none, and eight said they used pain medication, particularly in the longest race.

    As with all research, there are some caveats to consider. The marathon study used walking as a comparison rather than having participants sit quietly, meaning the control condition still involved mild physical exertion. Participants also selected their own running and walking speeds, which preserved a realistic race environment but introduced variation in how hard each individual was working.

    “I have reasonable confidence in the main findings, particularly because the increases in AEA were consistent across the marathon and ultramarathon studies and align with previous research,” McCartney told PsyPost. “However, there are some limitations worth considering. Measuring endocannabinoids in blood can be technically challenging, and although the authors used established analytical methods, they don’t explicitly report whether these methods were validated.”

    “I’d also have liked more information about what participants ate during and after exercise,” McCartney added. “We know that nutrient intake can influence blood AEA concentrations, so it’s possible that dietary behavior affected the measures.”

    The authors describe their laboratory analysis as following established, standardized protocols, including adding chemically labeled reference versions of each compound to every sample to allow exact measurement. They also acknowledge that participants’ nutrition, rest, and time of day were not fully controlled.

    Every participant also ran the marathon before doing the walking session, which the authors note may have raised anxiety at the start of the running day. The samples were also small, with 19 marathoners and between 7 and 16 runners at each ultramarathon distance, and no blood was drawn during the ultramarathons themselves.

    The emotional measures relied on brief, single-item rating scales, which capture only a snapshot of complex mental states like flow or emotional relief. Logistics during the ultramarathon also meant that pre-race samples for the 230-kilometer group had to be collected the previous evening rather than right at the starting line.

    “One important distinction is that we measured endocannabinoids in the blood, not directly in the brain,” Siebers pointed out. “Although our findings show substantial changes in circulating endocannabinoid concentrations, we cannot yet determine precisely what happens in the brain during prolonged running.”

    “Another important point is that the runner’s high is not simply caused by one molecule,” he added. “Endocannabinoids are probably part of a much larger and highly complex orchestra of neuromodulators, including dopamine, serotonin, endogenous opioids, and other signaling systems. Furthermore, not everyone experiences a runner’s high, and running does not necessarily become more enjoyable the longer someone continues.”

    When considering future research, McCartney highlighted both pharmacological and nutritional avenues for follow-up testing. “Ideally, I’d like to see whether blocking cannabinoid receptors prevents the runner’s high,” she said. “Unfortunately, the safety concerns associated with drugs like rimonabant make that a difficult experiment to conduct in humans!”

    Rimonabant, a drug that blocks the main cannabinoid receptor, was pulled from the European market in 2008 after it was linked to depression and suicidal thoughts.

    “More realistically, I’d be interested in seeing whether nutrition influences the endocannabinoid response to prolonged exercise,” McCartney told PsyPost, “particularly given that runners typically consume substantial amounts of carbohydrate during marathon and ultramarathon events.”

    Looking ahead, the authors hope to examine how these chemical messengers operate directly within the central nervous system during physical exertion.

    “One of my main interests is understanding how running influences mood changes and the brain itself,” Siebers said. “So far, our research has primarily focused on measuring endocannabinoids in peripheral blood. However, the runner’s high ultimately involves processes within the central nervous system, and we still know surprisingly little about what actually happens in the human brain during running. I would therefore like to investigate these central mechanisms more directly, potentially through neuroimaging and other methods that allow us to study neuromodulation in the brain.”

    “In addition, I am particularly interested in how the endocannabinoid system interacts with pain regulation during prolonged exercise,” he continued. “Why can some individuals continue running for hours despite considerable physical stress, while others experience increasing discomfort? Understanding these mechanisms could provide valuable insights not only into endurance exercise but also into pain regulation and mental health.”

    Beyond laboratory measurements, the researchers also reflected on the broader personal and evolutionary dimensions of sustained running.

    Siebers emphasized that the effect requires no outside substance. “What fascinates me is that our bodies can produce their own cannabis-like substances simply through physical activity,” he told PsyPost. “Under the right circumstances, this can contribute to a completely natural high, without consuming any external substance.”

    “For me, the most exciting message is that running is much more than moving our legs,” Siebers said. “It is a fascinating interaction between our body and brain, and understanding this interaction may help us discover why humans have developed such an extraordinary relationship with endurance running.”

    The study, “Endocannabinoid dynamics across marathon and ultramarathon running: evidence from two field studies,” was authored by Michael Siebers, Dana Huvermann, Christoph Siebers, Deborah Canales-Romero, Alexandra Florea-Ghile, Lina Keite, Lucas John, Moritz Munk, Roman Bizjak, Jens Witzel, Sebastian Schulz, Johannes Kirsten, Laura Bindila, Anke Hinney, Marijke Grau, Daniel A. Bizjak, Harald Engler, and Johannes Fuss.

    URL: psypost.org/your-body-makes-it

    -------------------------------------------------

    Private, vetted email list for mental health professionals: clinicians-exchange.org

    Unofficial Psychology Today Xitter to toot feed at Psych Today Unofficial Bot @PTUnofficialBot

    -------------------------------------------------

    #psychology #counseling #socialwork #psychotherapy @psychotherapist @psychotherapists @psychology @socialpsych @socialwork @psychiatry #mentalhealth #psychiatry #healthcare #depression #psychotherapist #RunnersHigh #Running #Marathon #Ultramarathon #EnduranceRunning #SportsScience #Neuroscience #Endocannabinoids #Anandamide #MentalWellness

  15. Nos artigos anteriores construímos uma visão cada vez mais completa do Apache Spark.

    Passamos por:

    Data
    ↓
    Partitions
    ↓
    Tasks
    ↓
    Executors
    ↓
    Shuffle
    ↓
    Joins
    ↓
    Spark SQL
    ↓
    Catalyst
    ↓
    Physical Plan

    Mas existe um recurso atravessando praticamente todas essas etapas:

    memória.

    Quando comecei a estudar problemas de memória no Spark, era tentador resumir tudo a:

    OutOfMemory
    ↓
    aumentar RAM

    Hoje eu vejo esse raciocínio como incompleto.

    Um problema de memória pode estar relacionado a:

    Driver
    Executors
    Partitions
    Shuffle
    Broadcast
    Cache
    Serialization
    Garbage Collection
    Python workers
    Off-heap/native memory
    Memory Overhead

    E aumentar memória sem descobrir qual desses componentes está causando o problema pode apenas tornar um Job caro antes de ele falhar novamente.

    A pergunta correta não é:

    Quanto de memória devo adicionar?


    É:

    Quem está consumindo memória, por quê, e em qual parte da arquitetura?


    1. Memória em uma aplicação Spark


    Vamos voltar à arquitetura básica:

    DRIVER
    │
    ▼
    Cluster Manager
    │
    ┌─────────┼─────────┐
    ▼ ▼ ▼
    Executor 1 Executor 2 Executor 3

    Temos dois contextos que precisam ser diferenciados imediatamente:

    Driver Memory

    e:

    Executor Memory

    Essa distinção é fundamental.

    Porque:

    Driver OOM

    e:

    Executor OOM

    podem ter causas completamente diferentes.

    2. Driver Memory


    O Driver coordena a aplicação.

    Ele mantém informações relacionadas a:

    • aplicação;
    • Jobs;
    • Stages;
    • Tasks;
    • scheduling;
    • metadados;
    • planos de execução;
    • resultados retornados ao Driver;
    • estado necessário para coordenar a computação.

    Conceitualmente:

    DRIVER
    │
    ┌──────────────┼──────────────┐
    ▼ ▼ ▼
    Planning Scheduling Metadata
    │ │ │
    └──────────────┼──────────────┘
    ▼
    Control

    Isso significa que o Driver não deveria ser tratado como destino para todo o dataset distribuído.

    Esse ponto parece óbvio.

    Até alguém executar:

    dados = df.collect()

    3. O perigo do collect()


    Considere:

    df.count()

    O processamento acontece de maneira distribuída e o resultado retornado é pequeno:

    123456789

    Agora compare com:

    dados = df.collect()

    collect() solicita que todos os registros do DataFrame sejam retornados ao Driver.

    Conceitualmente:

    Executor 1 ──────┐
    Executor 2 ──────┤
    Executor 3 ──────┼──► DRIVER
    Executor 4 ──────┤
    Executor 5 ──────┘

    Se o dataset possuir:

    500 GB

    e o Driver tiver:

    8 GB

    temos um problema bastante previsível.

    O Spark é distribuído.

    Mas acabamos de pedir:

    Traga tudo para uma única máquina.


    4. collect() não é ruim — o contexto é que importa


    Não existe problema em:

    df.limit(10).collect()

    quando sabemos que o resultado será pequeno.

    Também existem cenários legítimos em que precisamos trazer pequenas quantidades de dados ao Driver.

    O problema é usar collect() sem compreender:

    Distributed Dataset
    ↓
    Driver

    A pergunta antes de um collect() deveria ser:

    Qual o volume máximo que pode voltar para o Driver?


    Essa pergunta evita muitos problemas.

    5. Outros caminhos para sobrecarregar o Driver


    collect() é o exemplo mais conhecido, mas não é o único.

    Problemas de Driver também podem aparecer com:

    • resultados excessivamente grandes;
    • estruturas locais gigantes;
    • excesso de metadados;
    • quantidade extrema de Tasks;
    • operações que materializam dados no processo do Driver;
    • código Python executado localmente;
    • determinadas operações de visualização ou conversão.

    Por exemplo:

    pdf = df.toPandas()

    merece atenção.

    O resultado precisa caber na memória do processo que recebe esse DataFrame local.

    Ou seja:

    Spark DataFrame distribuído
    ↓
    toPandas()
    ↓
    DataFrame local
    ↓
    DRIVER

    Se os dados forem grandes, temos novamente uma concentração de memória.

    6. Executor Memory


    Agora vamos para os Executors.

    Eles executam as Tasks.

    Conceitualmente:

    Executor
    │
    ├── Task 1
    ├── Task 2
    ├── Task 3
    └── Task 4

    Durante a execução, memória pode ser necessária para:

    • processamento;
    • agregações;
    • joins;
    • sorting;
    • shuffle;
    • estruturas intermediárias;
    • cache;
    • dados serializados;
    • execução de código;
    • componentes fora do heap JVM.

    É aqui que começam vários problemas clássicos.

    7. Uma partição vira trabalho para uma Task


    Da Parte 3:

    Em uma determinada Stage, cada partição normalmente corresponde ao trabalho de uma Task.


    Então existe uma conexão direta:

    Partition
    ↓
    Task
    ↓
    Memory pressure

    Imagine:

    Partition 1 → 200 MB
    Partition 2 → 180 MB
    Partition 3 → 220 MB
    Partition 4 → 18 GB

    A Task responsável pela quarta partição terá um perfil completamente diferente das demais.

    Podemos observar:

    Task 1 → OK
    Task 2 → OK
    Task 3 → OK
    Task 4 → Memory Pressure

    Talvez o problema não seja:

    Executor com pouca memória.


    Talvez seja:

    Uma partição absurdamente maior que as outras.


    8. Particionamento e memória são inseparáveis


    Imagine um dataset de:

    1 TB

    distribuído em:

    10 partitions

    Simplificando muito:

    ≈ 100 GB por partition

    Agora considere:

    1000 partitions

    Teríamos algo mais próximo de:

    ≈ 1 GB por partition

    Isso não significa que uma Task precise manter toda a partição simultaneamente em memória.

    Mas o exemplo mostra uma relação importante:

    O tamanho e a distribuição das partições influenciam diretamente a pressão de memória das Tasks.


    É por isso que simplesmente aumentar spark.executor.memory pode esconder a causa real.

    9. Execution Memory


    Durante operações como:

    df.groupBy("customer_id").sum("value")

    Spark precisa de memória para executar estruturas intermediárias.

    Também em:

    df.orderBy("timestamp")

    ou em determinados joins.

    Podemos pensar conceitualmente:

    Executor Memory
    │
    ├── Execution
    │ │
    │ ├── Shuffle
    │ ├── Join
    │ ├── Sort
    │ └── Aggregation
    │
    └── Storage
    │
    ├── Cached Data
    └── Persisted Data

    No Spark moderno, execution e storage participam de um modelo de gerenciamento de memória integrado.

    Isso é importante porque a memória disponível não deve ser imaginada como caixas totalmente independentes e rígidas em todos os momentos.

    10. Storage Memory


    Agora imagine:

    df.cache()

    Quando o DataFrame é materializado, Spark pode manter partições para reutilização.

    Conceitualmente:

    Executor
    │
    ├── Execution Memory
    │
    └── Storage Memory
    │
    ├── Partition A
    ├── Partition B
    └── Partition C

    Isso pode ser extremamente útil.

    Se o mesmo dataset caro for utilizado várias vezes:

    Expensive computation
    ↓
    CACHE
    ↓
    ┌─────┼─────┐
    ▼ ▼ ▼
    Use 1 Use 2 Use 3

    evitamos recalcular repetidamente a mesma linhagem.

    Mas cache também custa memória.

    11. cache() não significa "deixe rápido"


    Esse é outro anti-pattern comum:

    df.cache()

    ser utilizado como se significasse:

    optimize(df)

    Não significa.

    Imagine um DataFrame de:

    800 GB

    que será utilizado apenas uma vez.

    Fazer cache pode simplesmente:

    • consumir memória;
    • provocar eviction;
    • aumentar pressão sobre o Executor;
    • competir com execution memory;
    • não trazer benefício relevante.

    Cache faz mais sentido quando existe reuso.

    Por exemplo:

    base = transformacao_cara(df)

    base.cache()

    resultado_a = base.groupBy("estado").count()
    resultado_b = base.groupBy("produto").sum("valor")
    resultado_c = base.filter("status = 'ACTIVE'")

    Agora existe um motivo claro:

    Expensive Base
    ↓
    CACHE
    ↓
    ┌────┼────┐
    ▼ ▼ ▼
    A B C

    12. Cache também é Lazy


    Considere:

    df.cache()

    Isso não significa necessariamente:

    Neste instante, todas as partições foram computadas e armazenadas.


    A materialização ocorre quando uma Action força a computação.

    Por exemplo:

    df.cache()

    df.count()

    Agora temos:

    cache()
    ↓
    mark for persistence
    ↓
    count()
    ↓
    compute partitions
    ↓
    store according to persistence strategy

    Lazy evaluation continua presente.

    13. persist()


    Além de:

    df.cache()

    podemos trabalhar com:

    df.persist()

    e escolher estratégias de persistência adequadas ao contexto.

    Conceitualmente, a persistência pode envolver combinações de:

    Memory
    Disk
    Serialization
    Replication

    A escolha depende de fatores como:

    • tamanho;
    • frequência de reuso;
    • custo de recomputação;
    • memória disponível;
    • tolerância a I/O.

    Novamente, não existe uma configuração universalmente melhor.

    14. E quando a memória não é suficiente?


    Agora chegamos a algo que apareceu na Parte 4:

    Spill


    Imagine uma Task realizando:

    Sort

    ou:

    Aggregation

    ou processamento relacionado a:

    Shuffle

    Ela utiliza estruturas em memória.

    Mas a quantidade necessária ultrapassa o que pode ser mantido eficientemente ali.

    Então parte dos dados pode ser enviada para disco.

    Conceitualmente:

    Task
    ↓
    Memory
    ↓
    Memory pressure
    ↓
    Spill
    ↓
    Disk

    Depois:

    Disk
    ↓
    Read
    ↓
    Continue processing

    Isso permite que determinadas operações continuem mesmo quando tudo não cabe simultaneamente em memória.

    Mas existe um preço.

    15. Spill troca memória por I/O


    Compare:

    Memory
    ↓
    CPU

    com:

    Memory
    ↓
    Disk Write
    ↓
    Disk Read
    ↓
    CPU

    Disco normalmente é muito mais lento do que memória.

    Então grandes volumes de spill podem transformar:

    Job

    em:

    Job lento

    Mesmo sem ocorrer um OutOfMemory.

    Essa é uma lição importante:

    Uma aplicação pode estar sofrendo de pressão de memória sem necessariamente falhar por OOM.


    Ela pode simplesmente ficar muito mais lenta.

    16. Shuffle + Memory + Spill


    Agora conectamos vários artigos.

    Considere:

    resultado = (
    vendas
    .groupBy("customer_id")
    .sum("valor")
    )

    Podemos ter:

    Partitions
    ↓
    Partial Aggregation
    ↓
    Shuffle Write
    ↓
    Network
    ↓
    Shuffle Read
    ↓
    Aggregation
    ↓
    Memory pressure
    ↓
    Spill
    ↓
    Disk

    Agora um simples:

    groupBy()

    ganha uma interpretação completamente diferente.

    17. Data Skew volta novamente


    Imagine:

    P1 = 200 MB
    P2 = 210 MB
    P3 = 190 MB
    P4 = 15 GB

    Durante uma agregação:

    P1 → OK
    P2 → OK
    P3 → OK
    P4 → Spill → Spill → Spill

    Ou pior:

    P4 → OutOfMemory

    A reação inicial pode ser:

    Aumentar executor memory.


    Talvez funcione.

    Mas talvez a pergunta correta seja:

    Por que existe uma partição de 15 GB quando as demais possuem aproximadamente 200 MB?


    Estamos novamente diante de:

    Data Skew

    A causa é distribuição.

    O sintoma aparece na memória.

    18. OutOfMemory não é um único problema


    Quando alguém diz:

    "Spark deu OOM."


    Ainda sabemos muito pouco.

    Precisamos perguntar:

    Onde?

    Por exemplo:

    Driver OOM?

    ou:

    Executor OOM?

    ou pressão fora do heap/container?

    Também precisamos perguntar:

    Em qual Stage?

    Em qual operação?

    Em todas as Tasks?

    Em uma única Task?

    Depois de um Shuffle?

    Durante Broadcast?

    Durante collect()?

    Essas perguntas mudam completamente a investigação.

    19. Um Driver OOM pode indicar problema de arquitetura


    Imagine:

    dados = df.collect()

    sobre um dataset enorme.

    Podemos aumentar:

    spark.driver.memory

    de:

    4 GB

    para:

    16 GB

    Depois:

    32 GB

    Depois:

    64 GB

    Talvez o Job finalmente funcione.

    Mas a pergunta continua:

    Por que estamos trazendo um dataset distribuído gigantesco para um único processo?


    Aumentar memória resolveu o sintoma.

    Talvez não tenha resolvido o design.

    20. Executor OOM também pode esconder outro problema


    Agora imagine:

    Executor OOM

    A reação:

    spark.executor.memory
    8 GB → 16 GB

    Mas talvez exista:

    uma partition = 40 GB

    Ou:

    join skewed

    Ou:

    broadcast excessivo

    Ou várias Tasks concorrentes disputando recursos.

    Ou consumo significativo fora do heap principal.

    Então:

    Executor OOM não significa automaticamente que o Executor precisa apenas de mais heap.


    21. spark.executor.memory


    Uma configuração conhecida é:

    spark.executor.memory

    Ela define a quantidade de memória heap disponibilizada ao processo Executor JVM.

    Por exemplo:

    --executor-memory 8g

    Mas existe uma armadilha conceitual importante:

    A memória total necessária por um Executor não é necessariamente igual ao valor de spark.executor.memory.


    Existe memória utilizada fora desse heap.

    E isso nos leva diretamente ao tema do material original que estudei:

    Memory Overhead

    22. O que é Memory Overhead?


    Uma aplicação Spark não utiliza memória apenas para o heap principal da JVM.

    Podemos pensar de forma simplificada:

    Executor Container / Process Environment
    │
    ├── JVM Heap
    │
    │ └── spark.executor.memory
    │
    └── Additional / Non-Heap Memory
    │
    ├── JVM overhead
    ├── native memory
    ├── Python processes
    ├── direct buffers
    └── other runtime overhead

    É essa segunda região que torna memoryOverhead tão importante.

    Dependendo do ambiente e do workload, um Executor pode morrer mesmo quando aparentemente existe heap suficiente.

    23. Um exemplo conceitual


    Imagine uma configuração:

    Executor Heap
    8 GB

    Isso não significa necessariamente:

    Executor total
    =
    8 GB

    O processo também precisa de espaço para outras necessidades.

    Podemos pensar:

    Container / Pod / Executor allocation

    ┌───────────────────────────────┐
    │ │
    │ JVM Heap │
    │ spark.executor.memory │
    │ │
    ├───────────────────────────────┤
    │ │
    │ Memory Overhead │
    │ │
    │ Native / Python / Direct / │
    │ JVM non-heap / other │
    │ │
    └───────────────────────────────┘

    Se a região adicional for insuficiente, o processo pode exceder os limites impostos pelo gerenciador de recursos.

    24. Por que isso aparece muito com PySpark?


    Em PySpark existe uma característica importante.

    Nosso código Python não transforma a JVM inteira em Python.

    Existe interação entre:

    JVM
    ↕
    Python worker

    Conceitualmente:

    Executor JVM
    │
    ├── Spark execution
    │
    └── Python worker
    │
    └── Python code

    Esses processos também consomem memória.

    Dependendo do workload, bibliotecas e operações utilizadas, isso pode se tornar relevante para o consumo total do Executor.

    Portanto, em PySpark precisamos olhar além de:

    JVM Heap

    25. Memory Overhead no material histórico


    Uma das anotações que motivou este capítulo tratava especificamente de problemas de memoryOverhead.

    Esse tipo de problema continua conceitualmente relevante.

    O que mudou ao longo dos anos foram:

    • versões do Spark;
    • nomes e comportamento de determinadas configurações;
    • resource managers;
    • defaults;
    • cálculo automático de overhead;
    • integração com containers;
    • Kubernetes;
    • execução Python;
    • mecanismos internos de memória.

    Por isso não considero uma boa prática pegar uma configuração antiga e simplesmente reproduzi-la hoje.

    O conceito continua válido.

    A configuração precisa ser analisada no contexto da versão e do ambiente atuais.

    26. Heap vs. Off-Heap vs. Overhead


    Uma simplificação útil é:

    PROCESS MEMORY
    │
    ├── JVM Heap
    │
    ├── JVM Non-Heap
    │
    ├── Direct / Native Memory
    │
    ├── Python Worker Memory
    │
    └── Runtime Overhead

    Isso é mais próximo da realidade do que pensar:

    memory = spark.executor.memory

    Quando um container é encerrado por ultrapassar limite de memória, precisamos descobrir qual parte do consumo cresceu.

    27. Garbage Collection


    Agora vamos entrar em outro sintoma importante:

    GC


    A JVM gerencia automaticamente memória de objetos.

    Objetos são criados:

    Objects
    ↓
    Heap

    Depois deixam de ser necessários.

    O Garbage Collector precisa recuperar esse espaço.

    Em um cenário saudável:

    Application Work ███████████████████

    GC █

    Mas sob forte pressão podemos encontrar algo mais próximo de:

    Application ███████

    GC █████████████

    Ou seja:

    A aplicação passa tempo demais tentando gerenciar memória em vez de processar dados.


    28. GC alto é sintoma


    Assim como OOM, GC excessivo não deveria gerar automaticamente:

    Aumente a heap.


    Talvez tenhamos:

    • objetos demais;
    • partições grandes;
    • agregações pesadas;
    • estruturas intermediárias enormes;
    • cache excessivo;
    • serialização inadequada;
    • concorrência excessiva por Executor.

    Precisamos descobrir por que a memória está sob pressão.

    29. Mais cores por Executor também afetam memória


    Imagine:

    Executor
    8 cores

    Dependendo da configuração, várias Tasks podem executar simultaneamente nesse Executor.

    Conceitualmente:

    Executor Memory
    │
    ┌────┼────┬────┬────┬────┐
    ▼ ▼ ▼ ▼ ▼ ▼
    T1 T2 T3 T4 T5 ...

    Cada Task pode precisar de memória.

    Então existe uma relação:

    mais Tasks concorrentes por Executor
    ↓
    mais competição pela memória disponível

    Isso mostra por que tuning não deveria analisar:

    executor memory

    isoladamente.

    Precisamos olhar para:

    Executor Memory
    +
    Executor Cores
    +
    Partition Size
    +
    Task Behavior

    30. Executors gigantes também não são automaticamente melhores


    Poderíamos pensar:

    1 Executor
    64 cores
    256 GB RAM

    Parece poderoso.

    Mas Executors gigantes podem trazer trade-offs relacionados a:

    • concorrência;
    • garbage collection;
    • blast radius de falha;
    • utilização;
    • scheduling;
    • memória compartilhada entre muitas Tasks.

    No outro extremo:

    64 Executors
    1 core
    4 GB

    também possui trade-offs.

    Não existe um tamanho universal.

    Precisamos equilibrar:

    cores
    memory
    parallelism
    partition size
    workload
    cluster manager

    31. Broadcast também consome memória


    Na Parte 5 vimos:

    from pyspark.sql.functions import broadcast

    resultado = grande.join(
    broadcast(pequena),
    "id"
    )

    A estratégia pode evitar um shuffle grande.

    Mas existe um custo:

    Small Table
    ↓
    Broadcast
    ┌──┼──┐
    ▼ ▼ ▼
    E1 E2 E3

    Cada Executor precisa conseguir trabalhar com a estrutura transmitida.

    Se tentarmos broadcast de algo grande demais, podemos criar pressão significativa de memória.

    Novamente:

    Network optimization
    ↕
    Memory cost

    Sistemas distribuídos são cheios de trade-offs.

    32. Cache também compete por recursos


    Imagine:

    df_a.cache()
    df_b.cache()
    df_c.cache()
    df_d.cache()

    Pode parecer:

    Quanto mais cache, melhor.


    Mas:

    Cache A
    Cache B
    Cache C
    Cache D
    ↓
    Storage Pressure
    ↓
    Eviction / recomputation / resource competition

    Cache deveria ser uma decisão baseada em:

    reuse frequency
    ×
    recomputation cost
    ×
    available resources

    e não um reflexo automático.

    33. unpersist()


    Se um dataset não será mais reutilizado, podemos liberar sua persistência:

    df.unpersist()

    Isso comunica:

    Não preciso mais manter essas partições persistidas.


    Em pipelines longos isso pode ser importante.

    Por exemplo:

    Phase A
    ↓
    cache intermediate
    ↓
    reuse several times
    ↓
    phase completed
    ↓
    unpersist
    ↓
    free resources for Phase B

    Gerenciamento de memória também faz parte do design do pipeline.

    34. O Spark UI volta a ser essencial


    Se existe problema de memória, não quero começar alterando configurações.

    Quero observar.

    No Spark UI e métricas relacionadas, procuro sinais como:

    Task Duration
    GC Time
    Shuffle Read
    Shuffle Write
    Spill
    Storage
    Executor behavior
    Failed Tasks
    Skew

    Também observo logs.

    A pergunta é:

    O que aconteceu antes da falha?


    35. Um padrão de investigação


    Imagine:

    Job falhou
    ↓
    Executor lost
    ↓
    Memory-related error

    Meu raciocínio começaria assim:

    Qual Stage?
    ↓
    Qual operação?
    ↓
    Join?
    Aggregation?
    Sort?
    UDF?
    Cache?

    Depois:

    Todas as Tasks falharam?
    ↓
    ou apenas algumas?

    Se apenas algumas:

    Possível skew?

    Depois:

    Qual tamanho das partitions?
    Quanto shuffle?
    Quanto spill?
    Quanto GC?

    Só então:

    Heap insuficiente?
    Overhead insuficiente?
    Particionamento ruim?
    Broadcast inadequado?
    Concorrência excessiva?

    36. Caso 1 — Driver morrendo


    Sintoma:

    Driver OutOfMemory

    Código:

    dados = df.collect()

    Dataset:

    120 GB

    Driver:

    8 GB

    Diagnóstico provável:

    Distributed Data
    ↓
    collect()
    ↓
    Single Process
    ↓
    OOM

    Solução arquitetural:

    Não coletar o dataset inteiro.


    Talvez:

    df.write.parquet(
    "/data/output"
    )

    ou continuar o processamento distribuído.

    A solução principal não é necessariamente:

    8 GB → 128 GB

    37. Caso 2 — Uma Task morre repetidamente


    Sintoma:

    Stage 12

    199 Tasks → OK
    1 Task → FAIL

    Isso é extremamente informativo.

    Talvez tenhamos:

    Data Skew

    ou uma partição muito maior.

    Se aumentarmos memória de todos os Executors:

    Cluster cost ↑

    para resolver uma única partição anormal, talvez estejamos atacando o lugar errado.

    Precisamos investigar a distribuição.

    38. Caso 3 — Todas as Tasks sofrem Spill


    Imagine:

    Task 1 → heavy spill
    Task 2 → heavy spill
    Task 3 → heavy spill
    Task 4 → heavy spill
    ...

    Agora talvez tenhamos um problema sistêmico.

    Possíveis causas:

    Partitions muito grandes
    Memory insuficiente
    Join pesado
    Sort pesado
    Aggregation pesada
    Task concurrency

    Nesse cenário, ajustar recursos pode realmente fazer parte da solução.

    Mas ainda precisamos medir.

    39. Caso 4 — OOM depois de Broadcast


    Imagine que:

    Job funcionava

    e alguém adicionou:

    broadcast(dim)

    Agora Executors começam a morrer.

    Pergunta:

    Qual o tamanho real de dim?

    Talvez:

    "small table"

    tenha crescido.

    Ontem:

    50 MB

    Hoje:

    6 GB

    Uma otimização válida no passado pode se tornar um problema quando os dados mudam.

    Isso é importante:

    Performance depende também da evolução dos dados.


    40. Caso 5 — PySpark e memória externa ao heap


    Imagine:

    spark.executor.memory

    aparentemente confortável.

    Mas containers continuam sendo encerrados por memória.

    Agora precisamos olhar para:

    JVM Heap
    +
    Python workers
    +
    Native memory
    +
    Direct buffers
    +
    Other overhead

    É exatamente nesse tipo de cenário que compreender memoryOverhead deixa de ser detalhe e passa a ser parte do diagnóstico.

    41. Não ajuste memoryOverhead às cegas


    Se um Executor morre por ultrapassar limites externos ao heap, aumentar overhead pode ser apropriado.

    Mas ainda precisamos perguntar:

    Por que esse consumo existe?

    Pode ser:

    • Python;
    • bibliotecas nativas;
    • buffers;
    • comportamento da JVM;
    • volume de dados;
    • operação específica.

    A configuração correta depende do workload e do ambiente.

    Por isso evito recomendações como:

    sempre configure X GB

    ou:

    sempre use Y%

    sem contexto.

    Defaults e comportamentos também evoluem entre versões.

    42. Memória em Kubernetes


    Em ambientes containerizados, a questão fica ainda mais visível.

    Podemos pensar:

    Kubernetes Pod
    │
    └── Executor
    │
    ├── JVM Heap
    ├── Non-Heap
    ├── Native
    ├── Python
    └── Overhead

    O Pod possui limites.

    Não basta a JVM achar que possui heap suficiente.

    O consumo total do processo e componentes associados precisa respeitar os recursos disponíveis.

    Esse é um dos motivos pelos quais problemas modernos de Spark precisam ser analisados também no nível da infraestrutura.

    43. Memória em YARN


    Em ambientes YARN, existe raciocínio semelhante.

    O Executor executa dentro de recursos controlados pelo gerenciador do cluster.

    Historicamente, muitos erros de memoryOverhead ficaram conhecidos justamente em ambientes onde o container ultrapassava seu limite mesmo quando a heap configurada parecia aceitável.

    O princípio permanece:

    JVM Heap
    ≠
    Total Process Memory

    44. A configuração depende do ambiente


    Hoje Spark pode rodar em diferentes contextos:

    Standalone
    YARN
    Kubernetes
    Managed Platforms
    Cloud Services

    Isso significa que recomendações de memória precisam considerar:

    • Spark version;
    • cluster manager;
    • container limits;
    • JVM;
    • Python;
    • workload;
    • plataforma gerenciada.

    Uma configuração copiada de um artigo antigo pode estar:

    correta historicamente

    e:

    inadequada atualmente

    ao mesmo tempo.

    Esse é exatamente o tipo de cuidado que estou aplicando ao revisitar meu material antigo nesta série.

    45. Um modelo mental melhor para OOM


    Em vez de:

    OOM
    ↓
    More Memory

    prefiro:

    OOM
    │
    ┌──────────┴──────────┐
    ▼ ▼
    Driver? Executor?
    │ │
    ▼ ▼
    collect()? Which Stage?
    toPandas()? │
    metadata? ▼
    Which Operation?
    │
    ┌──────────┼──────────┐
    ▼ ▼ ▼
    Skew Shuffle Broadcast
    │ │ │
    └──────────┼──────────┘
    ▼
    Partition Size
    │
    ▼
    Heap or Overhead?
    │
    ▼
    Root Cause

    Esse modelo evita tratar todos os erros de memória como iguais.

    46. Performance tuning começa com observabilidade


    Imagine dois engenheiros.

    O primeiro vê:

    OutOfMemoryError

    e imediatamente altera:

    spark.executor.memory

    O segundo investiga:

    Stage
    Tasks
    Partition distribution
    Shuffle
    Spill
    GC
    Executor logs
    Physical plan
    Data volume

    O segundo talvez leve alguns minutos a mais antes de alterar a configuração.

    Mas a chance de resolver a causa real é muito maior.

    Essa é uma diferença importante entre:

    configuration tuning

    e:

    performance engineering

    47. Um checklist para problemas de memória


    Quando encontro um problema de memória em Spark, quero responder:

    • O erro aconteceu no Driver ou Executor?
    • Qual Stage estava executando?
    • Qual operação estava acontecendo?
    • Existe collect()?
    • Existe toPandas()?
    • Existe broadcast?
    • Existe cache excessivo?
    • As partições estão equilibradas?
    • Existe data skew?
    • Qual o tamanho das maiores Tasks?
    • Existe Shuffle?
    • Quanto?
    • Existe Spill?
    • Quanto?
    • Quanto tempo está sendo gasto em GC?
    • Todas as Tasks sofrem ou apenas algumas?
    • Existem Python workers?
    • Existe consumo nativo relevante?
    • O limite do container está sendo ultrapassado?
    • O problema é heap ou overhead?
    • A configuração corresponde à versão e ao cluster manager utilizados?

    Só depois:

    Qual configuração preciso alterar?


    48. O que eu evitaria fazer automaticamente


    Se o Job estiver lento ou falhando, eu evitaria começar por:

    dobrar executor memory

    ou:

    dobrar driver memory

    ou:

    aumentar memoryOverhead arbitrariamente

    ou:

    cachear tudo

    ou:

    reduzir o número de partitions sem medir

    ou:

    aumentar o cluster

    Todas essas ações podem ser válidas.

    Mas nenhuma delas deveria substituir diagnóstico.

    49. Memória, performance e custo


    Em cloud, existe ainda outra dimensão.

    Imagine:

    Executor Memory
    8 GB

    e simplesmente dobramos para:

    16 GB

    em dezenas ou centenas de Executors.

    Talvez o Job fique estável.

    Mas talvez tenhamos acabado de aumentar recursos para compensar:

    Data Skew

    ou:

    repartition ruim

    ou:

    join inadequado

    ou:

    cache desnecessário

    Então temos:

    Problema arquitetural
    ↓
    Mais infraestrutura
    ↓
    Maior custo
    ↓
    Problema mascarado

    Performance tuning também é FinOps.

    50. A conexão entre tudo que vimos até aqui


    Agora podemos montar uma visão muito mais completa:

    DATA
    │
    ▼
    PARTITIONS
    │
    ▼
    TASKS
    │
    ▼
    EXECUTORS
    │
    ┌───────────┼───────────┐
    ▼ ▼ ▼
    Memory CPU Network
    │ │
    ▼ ▼
    Aggregation Shuffle
    │ │
    └───────────┬───────────┘
    ▼
    Spill
    │
    ▼
    Disk
    │
    ▼
    Performance
    │
    ▼
    Cost

    Agora adicione:

    Data Skew

    e podemos gerar:

    Uneven Partition
    ↓
    Huge Task
    ↓
    Memory Pressure
    ↓
    Spill / GC
    ↓
    Slow Task
    ↓
    Straggler
    ↓
    Slow Stage

    Isso mostra por que os capítulos anteriores estavam conectados.

    51. A principal lição deste capítulo


    Se eu pudesse resumir memória no Spark em uma frase:

    Problemas de memória frequentemente são sintomas de como os dados e a computação foram distribuídos.


    Nem sempre.

    Às vezes realmente precisamos de mais memória.

    Mas antes de aumentar recursos, quero saber:

    Quem está consumindo?
    ↓
    Onde?
    ↓
    Durante qual operação?
    ↓
    Por quê?

    Só então:

    Architecture
    +
    Configuration
    +
    Resources

    entram na solução.

    52. Como penso hoje


    Meu modelo mental deixou de ser:

    Spark OOM
    ↓
    Increase Memory

    e passou a ser:

    Spark OOM
    ↓
    Driver or Executor?
    ↓
    Heap or Overhead?
    ↓
    Which Stage?
    ↓
    Which Task?
    ↓
    Which Operation?
    ↓
    Partition Size?
    ↓
    Skew?
    ↓
    Shuffle?
    ↓
    Spill?
    ↓
    Broadcast?
    ↓
    Cache?
    ↓
    Python / Native Memory?
    ↓
    Root Cause
    ↓
    Then Tune

    Esse raciocínio é muito mais útil do que decorar valores de configuração.

    Próximo artigo


    Agora entendemos:

    Partitions
    ↓
    Tasks
    ↓
    Memory
    ↓
    Shuffle
    ↓
    Spill

    Mas existe outro conceito fundamental que apareceu desde os primeiros artigos:

    Lineage.

    Quando uma partição é perdida, como Spark sabe reconstruí-la?

    Por que RDD significa:

    Resilient Distributed Dataset

    ?

    Como Spark obtém tolerância a falhas sem simplesmente replicar toda computação intermediária?

    E o que acontece quando a linhagem fica grande demais?

    No próximo artigo vamos explorar:

    • RDD Lineage;
    • DAG;
    • fault tolerance;
    • recomputation;
    • cache vs. recomputation;
    • checkpoint;
    • persistência;
    • falha de Executor;
    • recuperação de partições;
    • por que Spark é "resilient";
    • e como essas ideias evoluíram nas APIs modernas.

    Vamos partir deste modelo:

    Source
    ↓
    Map
    ↓
    Filter
    ↓
    Join
    ↓
    Aggregate
    ↓
    Result

    para enxergar algo mais profundo:

    LINEAGE
    │
    ▼
    Source → Transform → Transform → Shuffle → Result
    │ │ │
    └──────────┴──────────┘
    │
    information needed
    for recomputation

    Essa é uma das ideias fundamentais que fizeram o Spark ser Spark.

    ← Parte 6: Spark SQL e DataFrames — do código ao plano de execução

    Próximo: Parte 8 — RDD Lineage e tolerância a falhas: como o Spark se recupera quando algo dá errado#cluster #spark #python #bigdata #software #coding #development #engineering #inclusive #community
    Como aprendi Apache Spark — Parte 7: Memória — Executors, Driver, Cache, Spill e OutOfMemory

  16. Reklam panelinde "lead" sayısı artarken satış ekibinin "bu lead'lerin hiçbiri alıcı değil" demesi, dijital pazarlamada en sık duyduğum cümlelerden biri. Ben Koray Yalçın; lead yönetimi, CRM mimarisi, dijital pazarlama ve yapay zekâ destekli otomasyonların kesiştiği projelerde çalışıyorum, özellikle gayrimenkul ve B2B tarafında. Bu cümlenin arkasında çoğu zaman teknik bir kopukluk yatar: Reklam platformu formun doldurulduğunu bilir, ama o kişinin üç hafta sonra showroom'a gelip sözleşme imzaladığını bilmez. Algoritma da doğal olarak form doldurmaya en yatkın kitleyi bulmaya devam eder, satın almaya en yatkın kitleyi değil.

    Bu boşluğu kapatmanın yolu, CRM'de oluşan "nitelikli lead", "randevu gerçekleşti" ve "satış kapandı" gibi olayları sunucu tarafından Meta Conversions API'ye (CAPI) geri göndermek. Bu yazı bir pazarlama rehberi değil; bu köprüyü kodla kurarken karşılaştığım tasarım kararlarını anlatıyor: kullanıcı verisinin normalizasyonu ve hash'lenmesi, olay kimliği ile tekilleştirme, zaman penceresi, yeniden deneme stratejisi ve izin kontrolü. Örnekler Python ama mantık her dile taşınabilir.

    Önce olay sözlüğü: Hangi CRM durumu hangi olay?


    Kod yazmadan önce yapılması gereken en önemli iş, CRM'deki aşamaları sınırlı ve anlamlı bir olay listesine eşlemek. Her aşama değişikliğini Meta'ya göndermek gürültü üretir. Benim kullandığım tipik eşleme şöyle:

    CRM olayıGönderilen olay adıNotForm / lead oluştuLeadGenellikle tarayıcı pikseli zaten gönderirTemsilci "nitelikli" işaretlediQualifiedLead (özel olay)Ölçüm kurgusuna göre seçilirRandevu gerçekleştiSchedule veya özel olay"Randevu alındı" değil, "gerçekleşti"Sözleşme imzalandıPurchasevalue ve currency zorunlu düşünülmeli


    Burada kritik nokta şu: Olay, CRM'de geri alınabilir bir alan değişikliğinden değil, kalıcı bir olaydan tetiklenmeli. Temsilci bir fırsatı yanlışlıkla "kazanıldı" yapıp beş dakika sonra geri alırsa, gönderilmiş bir Purchase olayını geri çekmenin pratik bir yolu yoktur. Bu yüzden ben aşama değişikliklerini doğrudan API'ye bağlamak yerine bir conversion_events tablosuna yazıyorum ve gönderimi kısa bir bekleme süresinden sonra yapan ayrı bir işçiye bırakıyorum.

    CREATE TABLE conversion_events (
    id BIGSERIAL PRIMARY KEY,
    event_id TEXT NOT NULL UNIQUE, -- tekilleştirme anahtarı
    event_name TEXT NOT NULL,
    lead_id BIGINT NOT NULL REFERENCES leads(id),
    occurred_at TIMESTAMPTZ NOT NULL, -- olayın gerçek zamanı
    value_minor BIGINT, -- kuruş/cent cinsinden
    currency CHAR(3),
    status TEXT NOT NULL DEFAULT 'pending', -- pending, sent, failed, skipped
    attempts INT NOT NULL DEFAULT 0,
    last_error TEXT,
    send_after TIMESTAMPTZ NOT NULL DEFAULT now() + interval '15 minutes'
    );

    send_after alanı, "yanlışlıkla kazanıldı" senaryosuna karşı küçük bir tampon. İşçi göndermeden önce fırsatın hâlâ aynı aşamada olup olmadığını kontrol eder; değilse kaydı skipped yapar.

    Kullanıcı verisini normalize etmek: Hash'ten önce gelen asıl iş


    CAPI, e-posta ve telefon gibi kişisel verilerin SHA-256 ile hash'lenmiş olarak gönderilmesini bekler. Çoğu ekip hashlib.sha256(email) yazıp işi bitmiş sayar. Sorun şu ki hash, girdideki tek bir boşluğu ya da büyük harfi tamamen farklı bir değere dönüştürür. Meta tarafındaki eşleşme de birebir karşılaştırmayla çalıştığı için normalizasyon hatası, sessizce düşük eşleşme oranı olarak geri döner.

    Benim sahada gördüğüm en yaygın hatalar:

    • E-postada baştaki/sondaki boşluklar ve büyük harfler.
    • Telefonun 0533 ..., +90 533 ..., 90533... gibi farklı biçimlerde saklanması.
    • İsimlerde Türkçe karakterlerin farklı yazımları ve "Dr." gibi önekler.
    • Boş alanların boş string olarak hash'lenmesi (boş string'in de bir SHA-256 değeri vardır ve anlamsız bir eşleşme anahtarı üretir).

    import hashlib
    import re
    import phonenumbers

    def _sha256(value: str) -> str:
    return hashlib.sha256(value.encode("utf-8")).hexdigest()

    def norm_email(raw: str | None) -> str | None:
    if not raw:
    return None
    v = raw.strip().lower()
    return v if "@" in v else None

    def norm_phone(raw: str | None, default_region: str = "TR") -> str | None:
    if not raw:
    return None
    try:
    num = phonenumbers.parse(raw, default_region)
    except phonenumbers.NumberParseException:
    return None
    if not phonenumbers.is_valid_number(num):
    return None
    # Ülke kodu dahil, yalnızca rakamlar, başta + yok
    return phonenumbers.format_number(num, phonenumbers.PhoneNumberFormat.E164).lstrip("+")

    def build_user_data(lead) -> dict:
    ud = {}
    if (e := norm_email(lead.email)):
    ud["em"] = [_sha256(e)]
    if (p := norm_phone(lead.phone, lead.country_code or "TR")):
    ud["ph"] = [_sha256(p)]
    if lead.external_id:
    ud["external_id"] = [_sha256(str(lead.external_id))]
    # Tarayıcıdan yakalandıysa hash'lenmeden gönderilen alanlar
    if lead.fbc:
    ud["fbc"] = lead.fbc
    if lead.fbp:
    ud["fbp"] = lead.fbp
    return ud

    Bir detay daha: Kıbrıs gibi çok uluslu alıcı kitlesi olan pazarlarda default_region sabit "TR" olamaz. İngiltere'den gelen bir lead'in 07... ile başlayan numarası Türkiye varsayımıyla ayrıştırılırsa geçersiz sayılır ya da daha kötüsü yanlış bir numara üretir. Bu yüzden formda ülke seçimini ayrı bir alan olarak tutmak, normalizasyonun doğruluğunu doğrudan etkiliyor.

    fbc, fbp ve external_id: Eşleşmeyi güçlendiren köprüler


    E-posta ve telefon tek başına çoğu zaman yeterli olur, ama iki alan eşleşme kalitesini belirgin biçimde artırır:

    • fbc: Reklam tıklamasıyla gelen fbclid parametresinden türetilen tıklama kimliği. Kullanıcı sitenize reklamla geldiyse _fbc çerezinde bulunur.
    • fbp: Pikselin tarayıcıya yazdığı _fbp çerezi.

    Bu değerler satış anında değil, lead oluştuğu anda yakalanmalı. Üç hafta sonra sözleşme imzalanırken kullanıcı tarayıcısında değil, satış ofisinde oturuyor. Bu nedenle form gönderiminde bu iki çerezi gizli alanlarla alıp lead kaydına yazmak, sonraki tüm offline olayların kalitesini belirliyor. Meta Lead Ads formlarından gelen lead'lerde ise platformun verdiği lead kimliğini saklamak aynı işi görür; CRM entegrasyonu senaryolarında bu kimliğin olayla birlikte gönderilmesi eşleşmeyi doğrudan kurar.

    external_id ise sizin CRM'deki kişi kimliğiniz. Hem piksel hem sunucu tarafında aynı değer (hash'lenmiş olarak) gönderilirse, aynı kişinin farklı olaylarını birbirine bağlamak kolaylaşır.

    event_id ile tekilleştirme: Aynı satışı iki kez saymamak


    CAPI'de iki ayrı tekrar riski vardır:

    1. Piksel ile sunucu çakışması: Lead olayını hem tarayıcı pikseli hem sunucu gönderiyorsa, iki olay aynı event_name ve aynı event_id ile gelmelidir. Meta bu ikiliyi tek olay olarak sayar.
    2. Yeniden deneme çakışması: Ağ zaman aşımı yüzünden isteğin ulaşıp ulaşmadığını bilmiyorsanız ve tekrar gönderirseniz, aynı event_id korunmalıdır.

    event_id rastgele üretilmemeli; olaydan deterministik olarak türetilmeli. Benim tercihim şu:

    def make_event_id(event_name: str, lead_id: int, stage_version: int) -> str:
    return f"{event_name.lower()}:{lead_id}:{stage_version}"

    stage_version, fırsatın o aşamaya kaçıncı kez girdiğini tutan bir sayaç. Böylece bir müşteri gerçekten ikinci bir daire satın alırsa yeni bir Purchase üretilir, ama aynı satış için yapılan iki gönderim aynı kimliği taşır. Veritabanındaki UNIQUE kısıtı da aynı olayın kuyruğa iki kez girmesini engeller.

    Zaman penceresi: event_time "şimdi" değil, olayın gerçek zamanıdır


    Offline satış entegrasyonunda en sık yapılan hata, event_time alanına gönderim anını yazmak. Olayın değeri, ne zaman gerçekleştiğiyle anlam kazanır; sözleşme salı günü imzalandıysa ve işçi çarşamba gönderdiyse, event_time salı olmalıdır.

    İkinci önemli nokta, Meta'nın kabul ettiği geriye dönük pencere. Bu yazıyı yazarken belgeler, olayların gerçekleştikten sonra sınırlı bir süre içinde gönderilmesini istiyor ve bu süre action_source değerine göre farklılaşabiliyor. Sınır zamanla değişebildiği için kodda sabit bir sayı gömmek yerine yapılandırmadan okuyorum ve pencereyi aşmış olayları göndermeyi denemek yerine skipped olarak işaretleyip raporluyorum:

    from datetime import datetime, timezone, timedelta

    MAX_AGE = { # yapılandırmadan gelir; güncel değeri resmi belgeden doğrulayın
    "system_generated": timedelta(days=7),
    "physical_store": timedelta(days=7),
    }

    def is_sendable(evt, action_source: str) -> bool:
    age = datetime.now(timezone.utc) - evt.occurred_at
    return age <= MAX_AGE.get(action_source, timedelta(days=7))

    Bu kontrolün pratik sonucu, satış ekibinin CRM'i zamanında güncellemesinin bir veri kalitesi konusu haline gelmesi. Sözleşmeyi on gün sonra sisteme giren bir ekip, reklam optimizasyonuna o satışı hiç kazandıramaz. Bu yüzden ben bu entegrasyonu kurarken satış ekibi için "sözleşme imzalandığı gün CRM'de kapanır" kuralını da süreç tarafında yazılı hale getiriyorum.

    action_source ve olay gövdesi


    Sunucudan giden olay gövdesinin iskeleti şöyle:

    def build_payload(evt, lead, action_source="system_generated") -> dict:
    data = {
    "event_name": evt.event_name,
    "event_time": int(evt.occurred_at.timestamp()),
    "event_id": evt.event_id,
    "action_source": action_source,
    "user_data": build_user_data(lead),
    }
    if evt.value_minor is not None:
    data["custom_data"] = {
    "value": evt.value_minor / 100,
    "currency": evt.currency,
    }
    return {"data": [data]}

    action_source alanı, olayın nerede gerçekleştiğini anlatır. Web formu için website, CRM'in kendi ürettiği aşama değişiklikleri için system_generated, satış ofisinde imzalanan sözleşme için physical_store gibi değerler kullanılabilir. Doğru değeri seçmek hem raporlamayı hem de uygulanan kuralları etkiler; bu yüzden olay sözlüğünde her olayın action_source değerini de sabitliyorum.

    value tarafında bir uyarı: Konut gibi yüksek tutarlı satışlarda gerçek sözleşme bedelini göndermek bazı ekiplerin istemediği bir şey olabilir. Bu durumda tutarlı bir "değer skalası" (örneğin ürün tipine göre sabit bir puan) kullanmak, optimizasyon sinyalini korurken hassas ticari bilgiyi dışarı çıkarmamanın bir yolu. Hangisi seçilirse seçilsin, tutarlılık önemlidir; ay ortasında yöntemi değiştirmek raporları kırar.

    Gönderim işçisi: Toplu istek, yeniden deneme ve hata sınıflandırma


    İşçinin görevi basit görünür ama hata sınıflandırması önemli:

    import requests, time

    def send_batch(events, leads, pixel_id, token):
    payload = {"data": []}
    for evt in events:
    payload["data"].extend(build_payload(evt, leads[evt.lead_id])["data"])
    url = f"https://graph.facebook.com/{API_VERSION}/{pixel_id}/events"
    resp = requests.post(url, params={"access_token": token}, json=payload, timeout=15)
    if resp.status_code >= 500 or resp.status_code == 429:
    raise RetryableError(resp.text) # üstel bekleme ile tekrar
    if resp.status_code >= 400:
    raise PermanentError(resp.text) # kaydı failed yap, alarm üret
    return resp.json()

    Kurallarım:

    • 5xx ve hız sınırı hataları yeniden denenir; bekleme süresi her denemede artar ve event_id aynı kalır.
    • 4xx hatalar (geçersiz parametre, süresi dolmuş token) yeniden denenmez. Tekrar göndermek sonucu değiştirmez, yalnızca log kirletir. Bunlar bir alarm kanalına düşer.
    • Token kod içinde değil, gizli değişken yönetiminde tutulur ve süresi izlenir. Sistem kullanıcısı token'ı kullanmak, bir çalışanın hesabı kapandığında entegrasyonun sessizce durmasını engeller.
    • Test olay kodu ile canlıya geçmeden önce olayların Events Manager'daki test ekranında doğru göründüğü doğrulanır.


    İzin ve veri minimizasyonu


    Kişisel veriyi üçüncü bir platforma, hash'lenmiş olsa bile, göndermek bir hukuki dayanak gerektirir. Türkiye'de KVKK, Avrupa'dan gelen alıcılar için GDPR bu çerçeveyi çizer. Benim teknik tarafta uyguladığım kurallar:

    • Lead kaydında reklam ölçümüne ilişkin izin durumu ayrı bir alan olarak tutulur ve işçi, izni olmayan kişi için olay göndermez.
    • Yalnızca eşleşme için gerekli alanlar gönderilir; adres, doğum tarihi gibi alanlar "olsa iyi olur" diye eklenmez.
    • İzin geri çekildiğinde, kuyruktaki bekleyen olaylar da iptal edilir.

    Bu bir hukuki görüş değil; ama izin kontrolünü kodun içine bir if olarak gömmek, sonradan "kimin verisi nereye gitti" sorusuna cevap verebilmeyi sağlıyor.

    Ölçüm: Entegrasyon gerçekten çalışıyor mu?


    Kurulumdan sonra baktığım üç gösterge var:

    1. Eşleşme kalitesi: Events Manager'daki olay eşleşme göstergesi. Düşükse ilk şüpheli normalizasyondur.
    2. Gecikme dağılımı: occurred_at ile gönderim zamanı arasındaki fark. Satış ekibinin CRM'i geç güncellemesi burada hemen görünür.
    3. CRM ile panel karşılaştırması: Aylık kapanan satış sayısı ile Meta'nın aldığı Purchase sayısı arasındaki fark. Birebir tutması beklenmez, ama fark aniden açılırsa token, izin veya şema tarafında bir şey bozulmuştur.


    Sıkça Sorulan Sorular


    Piksel zaten kurulu, neden ayrıca CAPI gerekiyor?
    Piksel yalnızca tarayıcıda olan olayları görür. Telefonla kapanan, satış ofisinde imzalanan ya da haftalar sonra gerçekleşen satışlar tarayıcıda olmaz. CAPI, bu olayları CRM'den doğrudan göndermeyi sağlar.

    E-postayı hash'lemeden göndersem Meta kendisi hash'lemez mi?
    Bazı resmi kütüphaneler hash işlemini kendisi yapar, ama kendi kodunuzla gönderiyorsanız normalizasyon ve hash sizin sorumluluğunuzdadır. Kontrolü elde tutmak, hatayı ayıklamayı da kolaylaştırır.

    Aynı satışı yanlışlıkla iki kez gönderirsem ne olur?
    Aynı event_name ve event_id ile gönderildiyse tekilleştirilir. Farklı kimlikle gönderildiyse iki satış sayılır; bu yüzden kimliği deterministik üretmek önemlidir.

    Satış on gün sonra CRM'e girildi, yine de gönderebilir miyim?
    Meta'nın kabul ettiği geriye dönük pencereyi aşmışsa olay reddedilir. Güncel sınırı resmi belgeden kontrol edin ve asıl çözümü süreçte arayın: satış, gerçekleştiği gün CRM'e girilmeli.

    Gerçek sözleşme bedelini göndermek zorunda mıyım?
    Hayır. Tutarlı bir değer skalası da optimizasyon için yeterli sinyal üretebilir. Önemli olan, seçilen yöntemin zaman içinde değişmemesi.

    Bu entegrasyon küçük ekipler için fazla karmaşık değil mi?
    Kuyruk tablosu, normalizasyon fonksiyonu ve bir gönderim işçisi birkaç yüz satır kod demek. Karşılığında reklam algoritması form dolduranları değil, satın alanları öğrenmeye başlar. Lead hacmi düşük ama satış değeri yüksek sektörlerde bu fark özellikle belirgin.

    Koray Yalçın — lead yönetimi, CRM mimarisi, dijital pazarlama ve gayrimenkul teknolojileri (PropTech) üzerine çalışıyorum. CRM'den reklam platformlarına geri bildirim kurarken sizi en çok hangi adım zorladı? Yorumlarda konuşalım.#backend #crm #api #marketing #software #coding #development #engineering #inclusive #community
    CRM'de kapanan satışı Meta Conversions API'ye geri bildirmek: Hash, event_id ve zaman penceresi üzerine geliştirici notları

  17. Sunday Morning Reading

    Writing a blog is an interesting experience. So is reading them. The best blogs are the ones where the person behind the keyboard shines through. You can say it takes courage to put yourself and your opinions out there. You would be correct. A lot of that got diminished when social media took over because of its hit and run nature. But blogs and the writers behind them are still there and surface now and again. Today’s Sunday Morning Reading features a few along with a few other tricks and treats. Hope you check them and the rest of the links out.

    Good writing stands out. Even on the Internet where it comes in small waves and ripples, subsequently washed away by more of the same, or often overwhelmed by the slop running alongside threatening to take it over. David Todd McCarty’s A Stream Has No Memory isn’t about that necessarily, and yet it is. All things flow.

    As I mentioned, personal blogging took a hit when the age of social media dawned. Yet, those that still exist, though not always as prolific, still provide insight when a writer allows you to peek into deeper waters. In many ways putting yourself out there, regardless of where, can easily become a personal hell. There’s been quite a controversy eddying about in tech circles about some who loudly condemned what was formerly Twitter reversing course and just as publicly announcing that they are returning. To each their own personal hell, I guess. I’ve stated my feelings about that here and here. Noted developer Marco Arment took to his blog with a post simply and aptly titled Community. It isn’t about what X marks the spot, it’s about what I believe deep down we all search for when we choose to share ourselves in our writing and our creative work. It can be lonely even with a magnitude of followers in whatever personal hell you choose to put yourself into.

    Jason Snell links to an excellent post by Cory Doctorow called Critique And Writing. Yes, it’s about AI and folks using it to generate editorial feedback, but it’s about so much more. We develop critical thinking by critiquing the work of others who work in the same field, whether it be writing or other disciplines. I had an acting professor once tell the class that the way we responded to the work of others told him more about how we were developing (or not) as actors as the work we ourselves did onstage.

    In the category of things we all share but wish we didn’t Neil Steinberg takes on scams and their persistent and constantly replicating existence in I Look Forward To Reviewing Your Proposal And Learning About The Quest For Pie.

    Natasha MH takes a look at perhaps the year’s most controversial film, Digger, in Hail The Conquering Heroes. That film is becoming a personal measuring stick for me as to who sees the world we live in as I do and who doesn’t.

    Halloween is upon us. With grandkids that’s quite a treat. But it can also be tricky. I’m headed there next weekend because my grandson has convinced us that we have to go trick-or-treating with him and his sister. He’s chosen for me to be costumed as a T-Rex. (Wearing costumes is my own personal hell.) Regardless of my escapades, I marvel at all of the decorations that abound and proliferate in yards up and down every block of every town rendering them all somewhat meaningless. Rex Huppke takes on the topic in America Has An Addiction To Giant Halloween Skeletons.

    And if Halloween spirits swirling amongst all of the evil things going on in the real world aren’t enough to scare the beejeebus out of you give a read to Max Seddon’s piece The Putin Whisperers about three men who worked to stop Putin from unleashing nuclear Armageddon. Some things are just damn scary.

    All things flow.

    (Image from The Cleveland Museum of Art on Unsplash.)

    Thanks for reading. Feel free to subscribe if you want. It’s free. If you’re interested in just what the heck Sunday Morning Reading is all about you can read more about the origins of Sunday Morning Reading here. If you’d like more click on the Sunday Morning Reading link in the category column to check out what’s been shared on Sunday’s past. You can also find more of my writings on Medium at this link, including in the publications Ellemeno and Rome. This site does not use affilate links.

     

    #ai #blog #blogging #books #Community #Culture #Internet #life #Movies #russia #SocialMedia #SundayMorningReading #Tech #ukraine #Writing
  18. Previews, Pre-Season, Betas, and Opening Nights

    There’s an old saying in the theatre biz. No show is ever really ready on opening night. It’s a cliché that has seen it’s time pass in the big money commercial circuit because so many producers run lengthy preview weeks, charging essentially, but not quite, full price to avoid reviewers publishing their criticisms until the show is officially open. The preview process began lengthing after the days of out-of-town tryouts came to an end, although we see that still happening occasionally as larger regional theatres will debut a work, allowing it to still be worked on, hoping that it will one day make it to Broadway.

    There was a famous production of Eugene O’Neil’s play Hughie, starring and directed by Al Pacino, that ran in previews for almost a month before finally opening. That led to a critic from Daily Variety breaking the only after opening night embargo a week early since the announced limited run would end up with less “real” performances than those in previews after the show officially opened. The show would go on to extend the run a couple of times.

    In smaller circuits the cliché still lives on, simply because of a lack of resources to run many preview performances in front of audiences to really gauge reaction before it officially opens. A show can look great in final dress rehearsals, but it’s never complete until there’s a paying audience of strangers sitting in the dark to tell if it works or not. The ever-present lack of time still breathes life into the cliché in ways that offer both hope and anxiety behind opening night curtains around the world.

    In the professional sports world teams play in a pre-season or spring training games that don’t matter while the players tune up for the real thing. Although in most of those types of meaningless games it’s really more like watching players audition than it is anything else. Occasionally a budding star emerges, but that’s atypical. Early “real” season games that do count (at full price) are when teams find out what they have, leading knowledgeable sports viewers knowing when it is time to pay real attention to a team’s chances or not.

    Those are two interests in my life. I’m a theatre professional (and geek) and I watch sports. Another is my interest in tech. In tech we have betas. Or we used to, when that was mostly for software. Now we’re just in previews, pre-season, or perpetual betas forever for both software and hardware. Which is somewhat understandable, yet weird, perhaps ironic, but ultimately a joke on the paying public, given the pace in which things are always advancing in tech, including the pace and price of advancement.

    We never seem to reach opening night, opening day or the end of a beta period in tech. Instead products and software are released incomplete, occasionally followed immediately by “leaks” that suggest the company that just took your money for it’s latest best product ever is working on fixing the things they knew were wrong for the next version when they released the product you just payed for.

    But you’re going to love it.

    It’s easier to swallow with software. It’s a bigger pill that sticks in the craw with hardware.

    It used to be that betas were for working out bugs. They still are to a degree, but now they’re just the next show in a never-ending season, or the latest minor-league call up. But you still pay full price for the game when the team needs to put a not ready for the big leagues pitcher on the mound just to fulfill its obligation to play the announced season.

    You can argue that there’s nothing wrong with the way things have evolved in tech because the financial equations are different. It requires a substantial upfront investment to create, produce and deliver new technology. You’d be mostly wrong, but you can argue it. Most of the costs in show biz happen upfront before a show even gets close to an audience, hopefully a large enough one in a long enough run to recoup the initial investment. It is a different equation in sports.

    The release of Apple’s iPhone Duo strikes me as an interesting entry in this evolution of consumer dynamics. Soon, perhaps too soon, before the product was released to the general public, leaks popped out that Apple was working on tweaks to two of the major criticisms of the device for the next generation — a larger model and adding FaceID. That followed criticism from reviewers.

    In general, most tech reviews I read, watched, or listened to made it very clear that the iPhone Duo was a first generation device with some rough edges that wasn’t for everyone, especially at the entry price. I can’t judge those reviews myself since I haven’t seen the product, but they mostly seemed very similar and to my mind fair. Some, sounding more like theatre critics or sport writers I’ve known, were more harsh, delivering criticism that might have prompted a closing notice being posted before intermission or an early game benching.

    Here’s where my three interests diverge a bit. In theatre the show can close early if it’s savaged or not enthusiastically endorsed by reviews. In sports a pro team can retool a bit by trading or signing free agents midseason. Tech companies have to play out the run with tech hardware until the next generation is ready.

    Given the leaks following the reviews I find it sort of funny that I’m in a place of feeling a bit sorry for the carriers that are offering great deals on the iPhone Duo subsidized by a three year contract. That’s a tough sell to anyone who pays attention, though admittedly most won’t if they’re hot to trot for the new shiny folding phone from Apple.

    It’s my hunch, and only a hunch, that Apple knew these criticisms were coming. Even so, it’s one thing to prepare the next version hoping to make changes that advance a platform, it’s another to make them in reaction to negative press once the product is unveiled. It sets you up in the next round for being congratulated for fixing what was wrong the last time.

    In the theatre if a joke doesn’t land, you can replace the joke in previews. In sports you bench a player or fire a coach. With tech hardware it’s not that easy changing things before it becomes a punch line. (See the Vision Pro.)

    My second hunch, only a hunch, is that the iPhone Duo will eventually become a successful part of Apple’s lineup and get past what feels like a rough opening. I don’t think it will enter into Vision Pro punchline territory. Critics of all human endeavors need something to criticize as much as companies need to produce the next thing. It’s a symbiotic relationship that feeds on itself. And the always distracted general public has short-term memory bordering on amnesia.

    It’s my wish that tech companies, like theatre companies and sports teams, would figure out a better path to the success they seek. Sure, you might be able to fool some of the people all of the time. But for the most part folks figure it out on their own. Some of the time. And that some of the time is what everybody on the producing end of things counts on.

    Thanks for reading. You can subscribe to this blog if you care to. You can also find more of my writings on a variety of topics on Medium at this link, including in the publications Ellemeno and Rome. I can also be found on social media under my name as above. This site does not use affilate links.

     

    #Apple #iPhone #iPhoneDuo #reviews #Sports #Tech #technology #TheaterOfTheMind #Theatre #Writing
Share on Mastodon

Enter the server where you have an account.