TinyPilot: Month 29

Michael Lynch

TinyPilot: 29ヶ月目

原文は Michael Lynch により に公開されました。 このブログを購読する

一行サマリー

長期タスクが止まったら要注意です。

ハイライト

  • TinyPilotは月間収益11万2,000ドルを達成し、初めて6桁の大台を突破しました。
  • TinyPilotのフルフィルメントチームにどれだけ余力があるかを、私は大きく見誤っていました。
  • 長期タスクは、リソース枯渇が迫っていることを知らせるカナリアになり得ます。

目標の達成度

毎月初めに、その月に達成したいことを宣言しています。結果は以下の通りです。

TinyPilotのフルフィルメントを3PL業者へ移行する準備

  • 結果: 単一の低ボリューム製品でオンボーディングを開始
  • 評価: B

現地スタッフがこの作業に充てられる余力を、私は過小評価していました。予想外の売上急増も重なり、自社のフルフィルメントワークフローを3PL業者向けに適応させる作業は進みませんでした。それでも、不完全なプロセスのまま前に進め、3PL業者によって時間が生まれた段階で改善していくことができます。

新しいサポートエンジニアのオンボーディングを継続

  • 結果: 2名のサポートエンジニアが、サポートチケットの約80%を自力で対応できるようになりました。
  • 評価: A

サポートエンジニアリングチームは、私の予想以上に力を発揮するようになっています。高度なサポートリクエストへの対応に加え、そもそもバグが発生しないように深く調査したり、TinyPilotの診断ログを改善したりしてくれています。

自分がクリティカルパスになるプロジェクトを減らす

  • 結果: 新しいプロジェクトを立ち上げたい衝動をこらえました。
  • 評価: B

新しいTinyPilotモデルのローンチには、常に私の時間が大きく割かれます。このプロセスは何度も経験しているので作業の多くは予測できますが、どれだけ計画しても必ず想定外の作業が出てくることも分かっています。余裕があると感じる日があっても、できるだけ自分の時間を空けておくようにしています。

TinyPilotの統計

指標2022年10月2022年11月前月比
ユニーク訪問者数7,9949,512+1,518 (+19%)
総ページビュー数17,86220,387+2,525 (+14%)
販売収益$85,834.20$107,223.10+$21,388.90 (+25%)
エンタープライズサブスクリプション$290.70$290.700
ロイヤリティ$5,544.12$4,402.50-$1,141.62 (-21%)
総収益$91,669.02$111,916.30+$20,247.28 (+22%)
利益$26,042.39$7,407.30-$18,635.09 (-72%)

TinyPilotはまたも過去最高の売上を記録し、総収益は11万2,000ドルに達しました。月次収益が6桁を超えたのは、TinyPilot史上初めてのことです。

この急増は、主にホームラボ愛好家に人気のYouTubeチャンネルLinus Tech TipsでTinyPilotが好意的に紹介されたことによるものです。レビュー自体は主に競合製品についてのものでしたが、チャンネルの登録者数が非常に多いため、その後2週間にわたって注文が大幅に増加しました。

異例のコスト高の中でも、3ヶ月移動平均の利益がしっかりプラスを保っているのは嬉しいことです。TinyPilotは通常の生産能力を超える分について、ケースを3Dプリントするために割増コストを払っていますが、1月に金属製ケースへ切り替えればコストは大幅に下がるはずです。

自分の時間を生み出すための時間すらない

11月の目標の一つは、フルフィルメントをサードパーティロジスティクス(3PL)業者へ移行し始めることでした。フルフィルメントチームのメンバーに、ワークフローを確認し、3PL業者へ引き継ぐ準備をするよう依頼しました。

翌週、Linus Tech Tipsの動画の影響で注文が急増したため、3PLへの移行に向けた調査は進みませんでした。さらに2週間後も、売上急増への対応に追われ、やはり進展はありませんでした。

次にフルフィルメント担当のスタッフと話したとき、通常こうしたイレギュラーなタスクにどれくらい余力があるのか尋ねてみたところ、答えはほぼゼロだということに驚きました。デバイスの組み立て、出荷、サポート対応といった短期的なタスクだけで、1週間の稼働時間がすべて埋まってしまうのです。

これは私にとって見覚えのある状況ですが、普段、短期的なキャパシティに余裕がないのは大抵私自身です。

どんなワークフローでも、時間を捻出する明白な方法はだいたい存在します。自動化したり、人を増やしたり、マネージドサービスに移行したりといったことです。ただ、ワークフローを変えることには摩擦コストが伴うのが難点です。

この数ヶ月、私はアウトソーシングや委任にかかる時間的コストについてきれいな グラフを描いてきました。そんな流れで、誰かにタスクを引き継ぐ前後で私の時間的コミットメントがどう変わるかを示したのがこちらです。

誰かを面接・オンボーディングする際に時間的コミットメントが増加し、その後引き継ぎが進むにつれて徐々に減少していく様子を示すグラフ

最初は、私がすべての作業を自分でやっているためタスクに時間がかかります。誰かを雇うと、タスク自体は自分で続けながら、採用や教育の作業も加わるため、さらに忙しくなります。新しいメンバーが完全に独り立ちして初めて、差し引きでプラスになりますが、タスクの複雑さによってはそれに数週間から数ヶ月かかることもあります。

実際には、1日に使える時間には限りがあります。1日の稼働時間の上限を考慮するとどうなるでしょうか。

1日あたりの稼働時間に上限があることを考慮した時間的コミットメントを示すグラフ。余裕がなく採用できない状態を表しています

あれ、短期的に採用や教育に充てる余力がないため、採用後の状態にすらたどり着けません。自分の時間を節約するための時間がないのです。

長期タスクをリソース枯渇の早期警報として使う

3PL業者への切り替えが遅れたことで、余力がなくなることをもっと早く察知する仕組みが必要だと気づきました。

現時点で最善だと思うのは、メンバー全員の短期タスクと長期タスクのバランスにもっと気を配ることです。たとえばサポートエンジニアの緊急の責務は、TinyPilotのヘルプフォーラムやCRMプラットフォームでカスタマーサポートのリクエストに対応することです。サポートの件数は波があるので、余裕があるときは、サポートリクエストに共通するパターンを探し、ヘルプ記事を公開したり、より根本的なバグ修正を調査したりしています。

TinyPilotの全員が、短期タスクと長期タスクを抱えています。

チーム短期タスク長期タスク
創業者チームマネジメント
ベンダーマネジメント
作業レビュー
不足している役割の穴埋め
マーケティング
対外的な執筆
戦略の見直し
採用・教育
フルフィルメント担当デバイスの組み立て
注文の発送
カスタマーサービス
カスタマーサポート用プレイブックの作成
マーケティング支援
サポートエンジニア技術的なサポート質問への対応ドキュメント作成
ブログ記事の執筆
困難なバグの調査
ソフトウェア開発者新機能のリリース
緊急のバグ修正
コードのリファクタリング
開発体験の改善
自動テストの作成
緊急でないバグの修正

長期タスクは、炭鉱のカナリアのような役割を果たします。あるチームの長期タスクの進捗が継続的に鈍ってきたら、キャパシティの上限に近づいている可能性が高いのです。そうなったら、担当範囲を減らしたり、人員を追加したりして負荷を下げる方法を探すべきです。

長期タスクを警報として使うには、2つの課題があります。1つ目は、長期タスクを最も頻繁に後回しにしているのが創業者チーム、つまり私自身だということです。私が手一杯のときは、他のチームの長期タスクの停滞に気づきません。気づいたとしても、対処する時間がありません。おそらく解決策は、自分が引き受けるプロジェクト数をより慎重に見極め、ワークフローの切り替えコストに充てる余力を残しておくことです。

もう1つの問題は、フルフィルメントチームの長期タスクが最も見えにくいことです。私たちの製造やフルフィルメントのプロセスは、毎週改善できるような性質のものではありません。しかし、フルフィルメントと製造を外部業者へ移行するにつれて、フルフィルメントチームの責務はカスタマーサポートへとシフトしていきます。カスタマーサポートには、サポートリクエストへの対応という短期的な作業と、内部プレイブックを磨くという長期的な作業の、より自然なバランスがあります。

Ansibleの穴から抜け出す

Ansibleはサーバーを自動で構成するためのツールです。私は7年間使っており、ホームラボにあるすべての仮想マシンをこれで管理しています。

2020年にTinyPilotの開発を始めたとき、Raspberry Piにコードをデプロイし、TinyPilotが必要とするOS機能を設定する方法が必要でした。リモートでのシステム構成はAnsibleの得意分野なので、うってつけでした。

TinyPilotを公開したとき、ユーザーにインストールしてもらう最も簡単な方法は、開発中に自分が使っていたワークフローを再現することでした。シンプルなインストールスクリプトを作成し、Ansible環境をブートストラップしてからAnsible経由でTinyPilotをインストールするようにしたのです。

当時、より一般的なインストール方法はDebianパッケージを使うことだと分かっていました。問題は、Debianパッケージの作り方をまったく知らず、とても手間がかかりそうに見えたことです。自分でaptリポジトリを立てなければいけないのか? リポジトリの鍵はどう管理するのか? TinyPilotはnginxに依存しているが、自分のパッケージからnginxをどう設定すればいいのか?

2年半が経ち、開発チームは私のAnsibleという選択のツケを払っています。TinyPilotの機能が増えるにつれて、Ansibleの設定は耐え難いほど複雑になりました。もしインストーラーが純粋なシェルスクリプトやDebianパッケージだったら、インストールや更新はおそらく10〜20秒で終わったでしょう。代わりに、Ansibleのオーバーヘッドによってインストールと更新に6分以上かかっています。

エンドユーザーへの影響だけでなく、Ansibleは開発リソースを食い潰す傾向があります。Ansibleのコードはデバッグが遅くて面倒で、特に継続的インテグレーション環境にないOSやアーキテクチャを扱うときはなおさらです。ちょっとした変更でも、しばしば1週間分の開発時間に膨らんでしまいます。

ここ数ヶ月、開発チームはAnsibleのコードをTinyPilot用のDebianパッケージへ移植する方法を模索してきました。嬉しいことに、すでに足がかりを得ています。ハイブリッドなソリューションを作り、TinyPilotのAnsibleロールが最新のTinyPilot Debianパッケージをインストールするようにしたのです。これにより、Ansibleのコードを少しずつ削り、Debianパッケージへ移していくことが容易になりました。

TinyPilotの開発を始めたときに知っておきたかった、Debianについてのことは次の通りです。

  • 自前のaptリポジトリを運用しなくても、スタンドアロンのDebianパッケージを作成・配布できます。
  • 適切なチュートリアルに従えば、シンプルなDebianパッケージの作成は15分でできます。
  • Docker QEMUを使えば、x64システムからARM用Debianパッケージをビルドできます。
  • コードがPythonのようなポータブルな言語で書かれているなら、QEMUをスキップしてアーキテクチャ非依存のDebianパッケージをビルドできます。
  • パッケージが他のパッケージを設定する必要がある場合、典型的な方法は、相手のパッケージが所有するファイルをいじるのではなく、設定ディレクトリにファイルを追加することです。
    • たとえば、TinyPilotのDebianパッケージは、/etc/nginx/sites-enabled/ディレクトリにファイルを追加することでnginxを設定できます。

Debianを学ぶ上で最も難しかったのは、ノイズの中から有用な情報を見つけることでした。リソースの多くは基本的に「9,000ページのDebianメンテナガイドを読んで、ただし古い部分は無視してください」と言うだけです。

最も役に立ったガイドは次の2つです。

Vincent氏は親切にもビデオ通話に応じてくれて、Debianパッケージに関する残りの疑問に答えてくれました。

サイドプロジェクト

ScreenJournal

私はテレビ番組や映画をよく観るのですが、友人に勧めたいと思っても、どの作品だったか忘れてしまうことがよくあります。

Goodreadsのように読書を記録するのと同じ感覚で映画やテレビを記録できるアプリを探してみましたが、思い描いていたものに合うものはありませんでした。友人たちがデフォルトで公開されるソーシャルアプリにうんざりしているように感じたので、おすすめを共有したい少人数の友人グループを作れるものが欲しかったのです。Twitterというより、Discordに近いイメージです。

友人と映画レビューを共有するためのアプリを作り始めました。ScreenJournalという名前です。

ScreenJournal上の私の映画レビューのスクリーンショット

ScreenJournalは、ソファで過ごす人のためのGoodreadsのようなものです。

まだ本番で使える段階ではありません。レビューは非公開で、単一ユーザーにしか対応していないからです。現時点では、1人用のプライベートな映画日記としてしか機能しませんが、次に予定している機能はマルチユーザー対応です。

ユーザー管理は悪名高いほど難しく、従来は自前での実装を避けてきました。ここ数年は、友人であるDavid Toth氏のUserKitというサービスを使ってユーザー管理を行ってきました。UserKitは素晴らしいのですが、まだ一般公開されていないため、自分のサーバーでScreenJournalを動かしたい他の開発者にとっては実用的ではありません。

Go用のオープンソースのユーザー管理フレームワークを探してみましたが、その大半は私が使いたくない外部サービスのOAuthに依存していました。残りはあまりにもヘビーで複雑で、使う気になれませんでした。

代わりに、危険を承知で自前のユーザー管理を実装しています。セッション管理にはjeffを、認証にはbcryptを使う予定で、うまくいくことを祈っています。

まとめ

できたこと

  • 3PL業者とのオンボーディングプロセスを開始しました。
  • TinyPilotのDebianパッケージをいくつかの重要な点で改善しました。
  • 海外のコントラクター向けにより良い決済プラットフォームを見つけました。
    • Deelの使い心地は悪く、Remote.comもあまり気に入らなかったので、Pilotを採用することにしました。

学んだこと

  • 長期タスクはリソース枯渇の優れた先行指標になります。
    • あるチームの長期タスクの進捗が継続的に鈍化しているなら、プロセスを切り替える余裕がなくなる前に対処することが重要です。
    • 創業者は長期タスクのための時間を確保しておくことが特に重要です。そうしないと、他のチームのリソース枯渇に効果的に対応できなくなるからです。
  • Debianパッケージングは、最初に思えるほど敷居は高くありません。

来月の目標

  • 3PL業者から最初の注文を発送する。
  • 次のTinyPilot Proリリースでコードコンプリートを達成する。
  • 1月に予定しているTinyPilot Voyager 2aのローンチに向けた準備をする。

この記事は「muse-spark-1.2-contributor」を使用して翻訳されました。

コメント