Select your current position
Pick a role and level — we'll show the growth path, skills and gap analysis.
Development path
Junior
0-2 years
Responsibility: Выполнение задач под руководством старших коллег. Изучение кодовой базы, стандартов и процессов команды. Написание кода по спецификациям, исправление простых багов, написание тестов.
Key skills:
Middle
2-5 years
Responsibility: Самостоятельная разработка фич от декомпозиции до деплоя. Участие в code review. Оптимизация производительности. Менторинг junior-разработчиков. Участие в архитектурных обсуждениях.
Key skills:
Senior
5-8 years
Responsibility: Проектирование архитектуры компонентов и сервисов. Решение сложных технических проблем. Ведение технического долга. Code review как gatekeeper качества. Менторинг middle-разработчиков. Выбор технологий для новых задач.
Key skills:
Lead / Staff
7-12 years
Responsibility: Техническое лидерство команды или направления. Проектирование системной архитектуры. Координация с другими командами. Формирование стандартов и best practices. Участие в найме. Планирование технического roadmap.
Key skills:
Principal
10+ years
Responsibility: Техническая стратегия на уровне компании или домена. Кросс-организационное влияние. Решение системных проблем бизнеса через технологии. Менторинг lead-инженеров. Публичное представление компании.
Key skills:
Gap analysis: skills to develop
To reach the next level you'll need to develop:
Implements Kafka integration for Elixir services: Broadway/Kafka consumer pipelines with backpressure, GenStage-based event processing, and efficient partition assignment for BEAM processes. Configures consumer groups leveraging Elixir's concurrency model. Implements fault-tolerant message processing with supervisor strategies.
Optimizes connection pooling in Elixir: configures DBConnection pool with queue_target and queue_interval for load shedding, implements connection health checking through Ecto after_connect callback. Monitors pool utilization through :telemetry events.
Implements CQRS in Elixir: uses Commanded for aggregates and process managers, configures EventStore for event persistence, creates read projections through Commanded.Projections.Ecto. Applies Elixir pattern matching for event handling and validation.
Independently implements tasks with Elixir Phoenix. Understands internals and optimizes performance. Writes tests.
Develops GraphQL API on Absinthe with nested types, enums and interfaces. Solves N+1 problem through Dataloader and batch resolvers. Implements Relay-style pagination with cursors, configures Absinthe middleware for logging and authentication.
Develops gRPC services in Elixir: implements gRPC servers through grpc-elixir with streaming support, integrates with OTP supervision trees for fault tolerance. Uses GenServer patterns for stateful gRPC processing and configures Telemetry for metrics.
Independently implements tasks with NATS / NATS JetStream. Understands internals and optimizes performance. Writes tests.
Independently designs schemas and optimizes queries with PostgreSQL. Understands indexing and query execution plans. Uses Ecto effectively.
Independently implements RabbitMQ messaging in Elixir with Broadway/AMQP library. Leverages OTP supervision trees for consumer fault tolerance. Configures prefetch counts and acknowledgment strategies for reliable processing.
Implements rate limiting in Elixir: uses ExRated or PlugAttack for Phoenix applications, configures ETS-based counters with periodic cleanup through GenServer. Implements per-user and per-IP limiting with custom key extraction from Plug.Conn.
Independently implements Redis caching patterns in Elixir services — pub/sub with Redix.PubSub for real-time features, sorted sets for leaderboards, and pipeline batching for performance. Understands Redis persistence options and memory management. Writes integration tests validating cache behavior and TTL correctness.
Develops structured REST APIs on Phoenix with versioning through router scopes. Implements pagination, filtering and sorting through Ecto queries. Applies Phoenix.View or Jason.Encoder for serialization, configures Plug pipelines for authentication.
Independently applies algorithmic thinking in Elixir: evaluates process message routing efficiency, selects appropriate data transformation algorithms with Enum/Stream, understands recursion optimization with tail-calls. Analyzes complexity of distributed computation patterns in OTP applications.
Independently applies async programming in Elixir/OTP: GenServer async calls, Task.async/await for concurrent operations, process supervision for fault tolerance. Understands trade-offs between synchronous and asynchronous message passing in OTP.
Develops structured API documentation for Phoenix with OpenAPI through open_api_spex. Configures Swagger UI for interactive endpoint testing. Generates automatic documentation from Ecto schemas and controllers, maintains changelog and guides through ExDoc.
Independently applies immutability patterns in Elixir backend services including persistent data structures, structural sharing, and efficient transformation pipelines with Enum and Stream. Writes pure functions that transform immutable state through GenServer callbacks and process-based state isolation. Understands performance implications of immutable data copying and leverages Elixir's BEAM-optimized memory model.
Independently designs schemas and optimizes queries with database indexing. Understands indexing and query execution plans. Uses Ecto effectively.
Independently applies code quality practices in Elixir/OTP development. Writes clean GenServer and Supervisor implementations with proper documentation. Understands trade-offs between process isolation and shared state. Reviews code for proper error handling, pattern matching clarity, and OTP convention adherence.
Independently designs schemas and optimizes queries with database migrations. Understands indexing and query execution plans. Uses Ecto effectively.
Independently applies concurrency patterns in Elixir/OTP: GenServer for stateful process management, Task for fire-and-forget concurrent operations, process linking and monitoring for fault tolerance. Explains trade-offs between different OTP concurrency abstractions in code review.
Independently applies monadic patterns (with/case chains, Result tuples) for composable error handling in Elixir pipelines. Understands trade-offs between Railway-oriented programming and exception-based flows. Explains functor mapping over Ecto changesets and option types in code reviews.
Independently designs schemas and optimizes queries with query optimization. Understands indexing and query execution plans. Uses Ecto effectively.
Applies FP principles naturally in Elixir: pattern matching, immutable data, pure functions, and pipe-based transformations. Understands when to use processes vs pure functions for state management. Reviews code for side-effect isolation and proper use of GenServer callbacks.
Works with messaging in Elixir: uses Broadway for concurrent message processing from RabbitMQ/Kafka/SQS, configures GenStage for internal event processing pipeline. Applies OTP supervisor patterns for fault-tolerant message processing with automatic restart.
Independently applies design patterns for Elixir: GenServer for stateful processes, Supervisor trees for fault tolerance, pipeline pattern with |> operator for data transformations, behaviour callbacks for polymorphism. Explains pattern trade-offs for OTP-based architectures.
Develops real-time functionality on Phoenix Channels with authorization through socket assigns and tokens. Implements presence tracking through Phoenix.Presence for online user tracking. Configures PubSub for distributed message broadcasting between nodes.
Independently designs schemas and optimizes queries with data modeling. Understands indexing and query execution plans. Uses Ecto effectively.
Implements API versioning in Phoenix through scope routes and Plug pipelines. Maintains parallel versions with separate controllers and view modules. Applies header-based versioning through custom Plug, ensures client migration between versions.
Independently implements tasks with caching strategies. Understands internals and optimizes performance. Writes tests.
Independently selects appropriate data structures in Elixir: keyword lists vs maps for configuration, ETS for read-heavy concurrent data, tuples vs structs for function return types. Understands trade-offs between immutable data structures and process-based state management in OTP.
Independently designs schemas and optimizes queries with transactions and concurrency. Understands indexing and query execution plans. Uses Ecto effectively.
Works with sharding in Elixir: implements dynamic Ecto.Repo selection through custom middleware, applies consistent hashing through :erlang.phash2 for shard routing, configures per-shard connection pooling through DBConnection. Handles cross-shard queries through Task.async_stream.