Professional Experience
Founder / Software Engineer, Bootspoon LLC (2021 – present)
I built a small, solo SaaS product. The app helped users store and organize
content they wanted to read later. The frontend was an SPA built using Vue and
Tailwind. It included data entry, an inbox-style workflow, tagging, live
updates as background jobs executed, search (using PostgreSQL FTS), and a
payments checkout flow powered by Stripe Checkout. Special attention was paid to
making the UI feel snappy, and degrading gracefully in poor network conditions.
The backend was powered by Node.js & Bun.js with PostgreSQL. The frontend was
built in Vue, communicating with the server using tRPC. The software integrated
with a 3rd-party API to enrich user data; this was handled using a background
job queue powered by PostgreSQL (Hatchet).
Both the frontend and backend were built with TypeScript, and end-to-end testing
was implemented with Playwright. The application was deployed using Docker
containers.
The project includes an internal dashboard built using React and deployed to
AWS, to monitor basic information about user signups and activity. Recent
activity is fetched from the app's internal API and persisted to DynamoDB.
I also performed freelance IT work. I worked with the clients to understand
their requirements, then delivered cost-effective and low-maintenance solutions
to small businesses on tight budgets.
Myxx, Consultant Software Engineer (2020 – 2021)
Myxx needed to scrape massive amounts of data from 3rd party websites, and keep
it fresh. I designed & built the distributed task platform to execute millions
of compute-intensive automated browsers. Due to unique requirements around job
scheduling, we outgrew Azure Queue Storage and I wrote a custom
PostgreSQL-powered job queue.
Implementation had to pivot several times as I learned that e.g., Azure
Functions hosts develop unrecoverable faults when under heavy load, or that
Durable Functions code cannot be updated without erasing the persistent job
state. All code was written in TypeScript.
I used Node.js Azure Functions as the command-and-control layer of the job
execution system. It integrated with a PostgreSQL database which stored task
definitions and metadata. This acted as a job queue, dispatching tasks based on
our customizable scheduling rules.
C&C submitted tasks to Azure Batch using Docker containers. These Node.js tasks
launched an automated Puppeteer browser, which navigated to the target website
and carried out the data collection. Collected data was persisted to Azure Blob
Storage.
LifeOmic, Senior Software Engineer (2019 – 2020)
LifeOmic wanted to offer service providers a video call interface to meet with
their clients. Using React Native and Node.js, I implemented the provider-side feature within the full-stack
application. Providers would receive a notification of an inbound call and
answer it.
The software allowed the user to mute, select & switch audio and video devices,
and displayed the presence of other users on the call. The user interface was
designed for 1:1 calls, and the underlying code supported group calls.
The project was deployed to AWS Lambda and DynamoDB. Frontend and backend code
was tested to 100% coverage, including our A/B test variations.
AdvisorEngine, Senior DevOps Engineer (2018 – 2019)
AdvisorEngine faced two issues: 1) Critical data imports had routine failures;
account reps didn't have answers when upset customers called. 2) Software
deploys required extensive cross-team planning and coordination, filled with
error-prone manual steps.
I built a Slack chatbot which connected & orchestrated disparate internal
systems, exposing a self-service interface to external teams. This returned
their ownership and autonomy, and made the status of business processes
immediately visible to all stakeholders. This project was implemented in
Node.js, leveraging AWS EKS (Kubernetes) and related services to deploy our
microservices.
This made a night-and-day difference for everyone involved. It eliminated a
frequent source of urgent blockers for the external teams, and saved 10+ hours
each week for the devops team.
My day-to-day work involved a variety of AWS services: we managed software
deployed to EKS using images stored in ECR, and maintained software hosted on
EC2. I wrote Lambda code to automate some tasks such as ECR cleanup, and Ansible
code to automate creation of AWS resources. Service data was stored in RDS
PostgreSQL, and service DNS was managed in Route 53. I used Jenkins with AWS
(EKS, S3, EC2) to orchestrate deployments of containerized microservices.
Dude Solutions, Senior DevOps Engineer (2017 – 2018)
Tech: Linux, Windows Server, Docker, Docker Swarm, Grafana, Logstash, Ansible
When a newly launched app faced severe performance and correctness challenges,
my team took initiative to troubleshoot. We implemented observability from the
ground up, which proved key to putting the project onto solid footing.
As the primary individual contributor, I instrumented every service and system
we could find. We gradually correlated a complex web of user & system activity
against performance drops and spiking error rates, identifying root causes and
sending that info upstream to the teams who could resolve it.
Align Technology, DevOps Engineer (2017)
Tech: AWS (CloudFormation, EC2, S3, DynamoDB, Lambda), Node.js, Vuex, TypeScript, Docker
Align powered their dental scanners and 3D modeling software with a fleet of
microservices. Their internal platform required routine maintenance and cost
management.
As a member of the devops team, I updated our infrastructure automation in
response to software teams' needs. I also wrote tooling to automatically
terminate unused AWS EBS volumes (saving $1,000+ per month), and identified
other cost-saving opportunities.
I also built tools to allow stakeholders on adjacent teams to self-service
access to information on the availability and status of microservices.
Cisco, Contract Software Engineer (2016)
Tech: Node.js, React, D3, MobX, OpenShift, Kubernetes, TypeScript, Redis
Cisco was developing an internal hosting platform on top of OpenShift
Kubernetes. To improve uptake of this new and unfamiliar technology,
stakeholders wanted a dashboard which visualized how the platform deployed and
scaled teams' services.
I built an interface which displayed real-time Kubernetes & OpenShift resource
states, using a graph-style visualization to depict the relationships between
deploy regions, pods and containers.
Youth Digital, Software Engineer (2015)
Tech: JavaScript (Node.js), Python, InstallBuilder
Youth Digital sold courses teaching children software development, 3D modeling,
and other skills. Kids' computers had to be configured with multiple pieces of
3rd party software, sample projects, custom plugins, and custom file extensions.
Our versions of apps could not conflict with off-the-shelf versions which may
already be installed.
I owned our software installer project, performing vendor selection and
implementing cross-platform installers for Windows and Mac. All courses'
installers leveraged reusable technologies and common patterns. Finicky
technical tasks were so easy a child could do them. Installer support tickets
fell from a routine pain point to virtually zero.
I also wrote a Blender plugin in Python to facilitate course content.
On-Site, DevOps Engineer (2013 – 2015)
Tech: Chef, Ubuntu Server, Xen, Tomcat, Apache, JRuby, Passenger, DB2, Python/Fabric
On-Site had a mature software product deployed to a fleet of bespoke,
hand-configured servers. They outgrew this model, and I was brought on to
automate stand-up and management of app servers.
I collaborated with the sysadmin and developer teams to understand the product's
hosting requirements. I wrote Chef code that fully bootstrapped a bare
virtual machine into a fully-functional app server, then worked with the
sysadmins to replace all existing servers with automated ones.
Lead time for new servers fell from more than a day down to minutes. A sysadmin
remarked it was the first time he took a week off without getting paged.
This work included using Python's Fabric utility to execute chef-solo on remote
machines.
Contactology, Software Engineer (2012 – 2013)
Tech: PHP, JavaScript, MySQL, Ubuntu Server, Gearman, AWS (EC2), HAProxy
Contactology had a mature, complex email marketing platform built by a handful
of developers. It operated at non-trivial scale, with business logic spread
between the full-stack web app and the background jobs that handled mail merge.
It used single-tenant database sharding across multiple MySQL active-active
pairs.
I wore many hats. In the morning I might rack a new server in the data center,
then after lunch I'd code up a new feature in PHP, then wrap up the day by
troubleshooting MySQL replication glitches. I leveraged EC2 instances for
software development and testing.