Project·Data management demo

Cattle Management Pipeline

Manage a cattle herd with a spreadsheet

Live demo·Simulated data·Last updated Oct 17, 2026

Python Neon Postgres Evidence Cloudflare Pages GitHub Actions

About this project

A small cattle-records system built to help visualize and manage herd changes. Logs are tracked using a spreadsheet and uploaded on a webpage.

This data is simulated using a Python script: about 75 head on the ranch now and 356 animals over almost three years (January 2024 to November 2026), with working days, moves between three pastures, calvings and sales, and prices that rise from year to year.

How it was built

In short, a spreadsheet goes through a validating function into a Postgres database, and a rebuild turns the new rows into the reports.

A lot of the decisions along the way came back to cost. The only thing I pay for is the domain name. The database, the hosting, the upload function, the bot check, and the automation all run on free plans, so the design had to fit inside their limits. The longer version, including the decisions and the parts that went wrong, is on the next page: How it was built →

Current Reports

How to use it

  1. Open the upload page and choose the event: worked (a working day, such as vaccinating or weighing, or a pregnancy check), moved, sold or deceased among animals already on the ranch, or a birth or a purchase. Pick the date, then download the pre-filled template. A blank one is there too.
  2. Check the rows. Animals already on the ranch get a row each, with the tag, type, gender and pasture filled in. A birth gets a row for each pregnant cow, with her tag in the mother column and the calf's pasture and birth year filled in. A purchase gets as many empty rows as you ask for, plus a Transactions row ready for the price. Delete the rows that do not apply and fill in what is left blank, such as a calf's tag or a weight. Only the tag, date and event type are required: for an animal already on the ranch, the server fills in the rest from its record, and a new animal needs a birth or purchase row first. The dropdowns in the template list the allowed values.
  3. Upload it. You can upload the .xlsx file, upload a CSV, or paste a link to a Google Sheet that is shared as "anyone with the link". Complete the quick "are you a person" check and press Upload.
  4. Read the answer. If a row has a problem, nothing is saved and the page lists every problem with its sheet, row and column, so you can fix it and try again. If everything passes, the whole file is saved at once, with a note for anything the server filled in for you, such as the tags on a purchase's Transactions row.
  5. See the result. The reports rebuild automatically. The page counts down three minutes and then asks you to refresh. Look up one of your tags on the Animal Lookup page.

To add an event to a single animal instead, open Animal Lookup, pick the tag and download its history. It has one row per event. Add a row at the bottom, leave the row_id column blank, and upload the file on the same page. Only the new rows are saved, the rows that were already there are skipped, and every new row must be for that animal. A sold or deceased animal takes no new events.

Please use made-up data. It is a shared demo: files are limited to 1 MB and 500 rows per tab, each visitor can save five uploads an hour, and uploaded data is removed after seven days.

Go to the upload page

Updates